I have a ListView with sections. And when a section appears, it becomes the place of another. That is, if the size of the ListView 30, then the section becomes the first item, and it turns out that only 29 points are shown.

Here is a picture where it is shown clearly.

enter image description here

I tried TYPE_MAX_COUNT = 2, 3 . Uselessly.

 @Override public int getViewTypeCount() { return TYPE_MAX_COUNT; } 

It feels like getViewTypeCount() works after getView() .

Here is the adapter itself:

 private List<VacancyModel> vacancyModelList; private LayoutInflater inflater; private SQLHelper sqlHelper; private static final int TYPE_SEPARATOR = 1; private static final int TYPE_ITEM = 0; private int rowType; public static String saveLastDate; private int newRecs = 0; public SuitableAdapter(Context context, int resource, List<VacancyModel> objects) { super(context, resource, objects); vacancyModelList = objects; sqlHelper = new SQLHelper(getContext()); inflater = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE); } @NonNull @Override public View getView(final int position, View convertView, @NonNull final ViewGroup parent) { ViewHolder holder = null; rowType = getItemViewType(position); if (convertView == null) { holder = new ViewHolder(); switch (rowType) { case TYPE_SEPARATOR: convertView = inflater.inflate(R.layout.suitable_separator_layout, null); holder.headerTv = (TextView) convertView.findViewById(R.id.section_header); break; case TYPE_ITEM: convertView = inflater.inflate(R.layout.row_layout, null); holder.tvProfession = (TextView) convertView.findViewById(R.id.tvProfession); holder.tvHeader = (TextView) convertView.findViewById(R.id.tvHeader); holder.tvSalary = (TextView) convertView.findViewById(R.id.tvSalary); holder.tvDate = (TextView) convertView.findViewById(R.id.tvPostCr); break; } convertView.setTag(holder); } else { holder = (ViewHolder) convertView.getTag(); } if (getItemViewType(position) == TYPE_SEPARATOR) { holder.headerTv = (TextView) convertView.findViewById(R.id.section_header); if (newRecs == 1) { holder.headerTv.setText("Новые вакансии"); newRecs = 0; } else { holder.headerTv.setText("Ранее просмотренные"); } } if (getItemViewType(position) == TYPE_ITEM) { final VacancyModel model = vacancyModelList.get(position); holder.tvProfession.setText(model.getProfession()); holder.tvHeader.setText(model.getHeader()); holder.tvSalary.setText(model.getSalary()); holder.tvDate.setText(model.getDate()); Date date; try { if (saveLastDate == null) { saveLastDate = model.getDate(); } else { date = stringToDate(saveLastDate); if (date.before(stringToDate(model.getDate()))) { saveLastDate = model.getDate(); } } } catch (ParseException e) { e.printStackTrace(); } } return convertView; } @Override public int getItemViewType(int position) { if (GlobalData.LoadDate(getContext()) == null) { return TYPE_ITEM; } else { VacancyModel model = getItem(position); if (model != null) { String newString = model.getDate(); String lastString = GlobalData.LoadDate(getContext()); Date newDate = null; Date lastDate = null; try { newDate = stringToDate(newString); lastDate = stringToDate(lastString); } catch (ParseException e) { e.printStackTrace(); } assert newDate != null; if (newDate.equals(lastDate)) { return TYPE_SEPARATOR; } else if (position == 0 && newDate.after(lastDate)) { newRecs = 1; return TYPE_SEPARATOR; } else { return TYPE_ITEM; } } else { return TYPE_ITEM; } } } @Override public int getViewTypeCount() { return 3; } @Override public int getCount() { return vacancyModelList.size(); } private Date stringToDate(String string) throws ParseException { return new SimpleDateFormat(("yyyy-MM-dd HH:mm:ss"), Locale.getDefault()).parse(string); } private static class ViewHolder { private TextView tvProfession; private TextView tvHeader; private TextView tvSalary; private TextView tvDate; private TextView headerTv; } 

    1 answer 1

    In order to display the separator as a separate element, quite complex logic is needed. Then there are 3 options:

    1. Display separator as part of normal element. Those. in suitable_separator_layout add a twist from row_layout and getView, when rowType == TYPE_SEPARATOR, you need to fill in tvProfession, tvSalary, etc.
    2. Use library
    3. To inherit from BaseAdapter, by the way you use some methods without going into details what exactly these methods are and what they do. For example getItem(position) . When creating an adapter, you should immediately determine where the separators will be and when you receive the model for display you need:

      final VacancyModel model = vacancyModelList.get (position - separatorsCount);

    Where separatorsCount needs to be calculated based on where you have separators relative to the current element. if you have a separator on position 0 and 3, then in order to display an element in position == 4, you need to take from the list a model with index 2, and not 4.

    And further:

     @Override public int getCount() { return vacancyModelList.size() + 2; } 

    Since you always have 2 separators.