Is there any way to re-index a SectionIndexer after new items are added to开发者_StackOverflow a ListView?
I found this solution, but the overlay is position in the top left corner after the SectionIndexer is refreshed.
Anyone have any ideas?
Once the FastScroller
(its in AbsListView
class that ListView
extends from) obtains your sections by calling SectionIndexer#getSections()
, it never re-obtains them unless you enable/disable fast-scrolling like mentioned in the link you mentioned. To get the value to be displayed on screen, FastScroller calls the section's toString method.
One potential solution is to have a custom SectionIndexer
that have the following characteristics:
- The sections array is of fixed length (max length of the expected number of sections. For example, if the sections represent English alphabet it will be 26)
- Have a custom object to represent sections, rather than using strings
- Overwrite the
toString
method of your custom section object to display what you want based on the current 'section values'.
-
e.g. In your custom SectionIndexer
private int mLastPosition;
public int getPositionForSection(int sectionIndex) {
if (sectionIndex < 0) sectionIndex = 0;
// myCurrentSectionLength is the number of sections you want to have after
// re-indexing the items in your ListView
// NOTE: myCurrentSectionLength must be less than getSections().length
if (sectionIndex >= myCurrentSectionLength) sectionIndex = myCurrentSectionLength - 1;
int position = 0;
// --- your logic to find the position goes in here
// --- e.g. see the AlphabeticIndexer source in Android repo for an example
mLastPosition = position;
return mLastPosition;
}
public Object[] getSections() {
// Assume you only have at most 3 section for this example
return new MySection[]{new MySection(), new MySection(), new MySection()};
}
// inner class within your CustomSectionIndexer
public class MySection {
MySection() {}
public String toString() {
// Get the value to displayed based on mLastPosition and the list item within that position
return "some value";
}
}
I found that the best way to do this is to call setContentView(R.layout.whatever)
and then re-populate the ListView
with your new adapter / new data items. This will redraw the ListView
with your new items and the FastScroll Overlay will appear in the correct place.
I found notifyDataSetInvalidated
working fine, here's the idea:
public class MyAdapter extends XXXAdapter implements SectionIndexer {
...
public void updateDataAndIndex(List data, Map index) {
// update sections
// update date set
notifyDataSetInvalidated();
}
}
update your data set and index (sections) somehow, and then notifyDataSetInvalidated
, the index will refresh.
You can force reloading sections list to ListView by listView.setAdapter(yourAdapter)
精彩评论