tonyc
tonyc

Reputation: 852

Re-index/Refresh a SectionIndexer

Is there any way to re-index a SectionIndexer after new items are added to 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?

Upvotes: 15

Views: 3958

Answers (4)

tse
tse

Reputation: 6079

You can force reloading sections list to ListView by listView.setAdapter(yourAdapter)

Upvotes: 0

xinthink
xinthink

Reputation: 1490

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.

Upvotes: 0

Karl Feinauer
Karl Feinauer

Reputation: 11

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.

Upvotes: 1

Thira
Thira

Reputation: 1575

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";
    }
}

Upvotes: 4

Related Questions