开发者

Re-index/Refresh a SectionIndexer

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)

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜