In my project I have class that extends ArrayAdapter<String>
and implements SectionIndexer
. When implementing methods getPositionForSection
and getSectionForPosition
I have found some strange behaviour.
Why section indexer works properly when getSectionForPosition
returns 0?
public int getSectionForPosition(int position) {
return 0;
}
this implementation is used in many tutorials, for example:
http://androidopentutorials.com/android-listview-fastscroll/
http://www.survivingwithandroid.com/2012/12/android-listview-sectionindexer-fastscroll.html
Documentation says that
Given a position within the adapter, returns the index of the corresponding section within the array of section objects.
so if my list have 5 items starting with letter "A" and some items starting with letter "B", then getSectionForPosition(5) should return 1.
While the basic functionality of the sectionIndexer
(scrolling through the section indices when pulling the scrollbar thumb) is unaffected, returning a constant in the method getSectionForPosition
can lead to a misbehaviour of the scrollbar positioning when swiping through the list (e.g. the scrollbar moving out of the window on the y-axis).
Apparently this misbehaviour only occurs when the list or single sections exceed a certain length, so for shorter lists the indexer might seem to work correctly (but in fact doesn't). I experienced this misbehaviour in larger lists when returning a constant in the above method several times and fixed it by implementing getSectionForPosition
in a correct way.
However, since it might be interesting for others I can provide a sample implementation of that method. Let azIndexer
be a HashMap
containing a correct section -> position
mapping of my indices and listItems
be the items arranged by the adapter. The following builds a position -> sectionIndex
mapping stored in positionIndexer
.
List<Integer> values = new ArrayList();
for (int i : azIndexer.values()) {
values.add(i);
}
values.add(listItems.size()-1);
Collections.sort(values);
int k = 0;
int z = 0;
for(int i = 0; i < values.size()-1; i++) {
int temp = values.get(i+1);
do {
positionIndexer.put(k, z);
k++;
} while(k < temp);
z++;
}
which will then be used in the getSectionForPosition
method:
@Override
public int getSectionForPosition(int position) {
return positionIndexer.get(position);
}