The fact is that I need to add a section in the job list. That is, "Previously viewed" and at the very beginning if there is an update one more section "New". So, I keep the date of the last viewed job in SharedPreferences and when I re-run I do a check in the adapter for a match and change convertView . But for some reason, everything is clumsy.

The section in place of a single vacancy becomes, however, this vacancy is not shown. And if you exit and immediately start the application, the section one point below is lowered, in place of another.

 public class SuitableAdapter extends ArrayAdapter<VacancyModel> { private List<VacancyModel> vacancyModelList; private LayoutInflater inflater; private static final int TYPE_SEPARATOR = 1; private static final int TYPE_ITEM = 0; private int rowType; public static String saveLastDate; public SuitableAdapter(Context context, int resource, List<VacancyModel> objects) { super(context, resource, objects); vacancyModelList = objects; 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); 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; return newDate.equals(lastDate) ? TYPE_SEPARATOR : TYPE_ITEM; } return TYPE_ITEM; } } @Override public int getViewTypeCount() { return 3; } @Override public int getCount() { return vacancyModelList.size() + rowType; } 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; } 

}

Question: Tell me, what's the problem?

  • Show the full stack trace. - post_zeew
  • 2
    Why not override the getItemViewType() and getViewTypeCount() methods implemented by the adapter, they are exactly for this, as in your question, designed and implement the mechanism more correctly - pavlofff
  • @pavloff did just that. NullPointer disappeared, but the change of the section, then down, then upward, did not improve. I realized that the section in place of a single vacancy becomes at the same time this vacancy is not shown. - DevOma
  • You need to add the number of delimiters, not rowType. And correct the element type definition. You do not take into account that the position includes separators - lllyct
  • Didn't quite understand which separators? Type of item? - DevOma

1 answer 1

NullPointerException is popping up because ListView is trying to reuse an already created View. This calls getView () with convertView! = Null. A new View is not created, and the layout of the already created View does not match the type of element. You need to override getItemViewType() and getViewTypeCount() , then ListView will know what type to use for this particular item.

In your case, getViewTypeCount should return 2, and getItemViewType - 0 or 1, depending on the item, as you define in getType (). It is very important that values ​​from 0 to count-1 be returned, due to the fact that ListView does not support non-consecutive type indexes. Now, if you used RecyclerView, then you could use layout as the type identifier.

You also have in determining the type of number of separators. Those. if you have the elements 0, 1, 2, 3, and the separator is between 1 and 2, then for the element "3" position should be 4, not 3. And the total number of elements should be items.size () + separators.size ()

  • And how to set the total number of elements? - DevOma
  • You must override the adapter's getCount() method. - lllyct
  • That's what I wrote, it seemed to solve the problem, but here rowType always remains unchanged, I think it is not updated, that is, it is updated inside getView. Is it possible to update it before getView works? @Override public int getCount() { return vacancyModelList.size() + rowType; } @Override public int getCount() { return vacancyModelList.size() + rowType; } - DevOma
  • It is necessary to update the code in the header, it is not clear what is behind the rowType and where you are updating it. - lllyct
  • updated, look please - DevOma