I'm trying to implement a listview that has fast scrolling with header previews. It looks like it's almost working correct, but I'm encountering some weird, bug-like behaviour. When I scroll down without using the fast scroll bar, the fast scroll bar disappears, and reappears only almost at the end. So there seems to be a gap or something like that.
My ListView's ArrayAdapter implements SectionIndexer and it's methods getSections(), getPositionForSection(int sectionIndex) and getSectionForPosition(int position). The getPositionForSection method is in my belief, the one causing trouble. When I log the value given by sectionIndex and I scroll down the list, this value exceeds the length of the actual sections (which is 20). This value comes from the SectionIndexer, not from myself. The Android refererence states:
If the section's starting position is outside of the adapter bounds, the position must be clipped to fall within the size of the adapter.
But when I clip the value to either 0 or section_size -1 (=19), the weird behaviour keeps appearing. Below is my ListView's ArrayAdapter implementing SectionIndexer. One note: the updateSections method is called from outside the adapter when the data changes in an AsyncTask. I hope someone knows what the problem is! Thanks in advance.
public class SoortArrayAdapter extends ArrayAdapter<Soort> implements SectionIndexer {
List<Soort> data;
private HashMap<String, Integer> alphaIndexer;
private ArrayList<String> sections;
public SoortArrayAdapter(@NonNull Context context, int resource, int textViewResourceId, List<Soort> data) {
super(context, resource, textViewResourceId, data);
this.data = data;
sections = new ArrayList<>();
alphaIndexer = new HashMap<String, Integer>();
}
private void updateSections() {
alphaIndexer.clear();
sections = new ArrayList<String>();
for (int i = 0; i < data.size(); i++) {
String s = data.get(i).getNaam().substring(0, 1).toUpperCase();
if (!alphaIndexer.containsKey(s)) {
alphaIndexer.put(s, i);
sections.add(s);
}
}
}
@NonNull
@Override
public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) {
if (convertView == null) {
convertView = getLayoutInflater().inflate(android.R.layout.simple_list_item_1, parent, false);
}
TextView textView = convertView.findViewById(android.R.id.text1);
textView.setText(data.get(position).getNaam());
return convertView;
}
@Override
public Object[] getSections() {
return sections.toArray(new String[0]);
}
@Override
public int getPositionForSection(int sectionIndex) {
System.out.println(sectionIndex);
if (sectionIndex >= sections.size()) {
return 0;
}
System.out.println("position for section=" + sections.get(sectionIndex));
return alphaIndexer.get(sections.get(sectionIndex));
}
@Override
public int getSectionForPosition(int position) {
String section = data.get(position).getNaam().substring(0, 1).toUpperCase();
System.out.println("section for position=" + section);
return alphaIndexer.get(section);
}
}