Shrikanth Kalluraya
Shrikanth Kalluraya

Reputation: 1119

Section Indexer Overlay is not updating as the adapter's data changes

I have implemented Section Indexer for an Adapter class which extends BaseAdapter. Now for the first launch Section Indexer is showing an overlay correctly. But when the contents of the list gets updated the Section Overlay does not get updated and gives ArrayOutOfBoundException. For one fix what i did is i made listview.setFastScrollEnabled(false); update the adapter contents; and then listview.setFastScrollEnabled(true); Now what happens is overlay gets updated but the Overlay is coming to the left top of the listview. How can I fix this.

Upvotes: 9

Views: 3455

Answers (5)

Matin Petrulak
Matin Petrulak

Reputation: 1107

I got similar problem using ResourceCursorAdapter . Section indexer was not updating after new adapter was set for list or swapCursor() method for updating cursor was called. I tried all the solutions posted on StackOverflow without any success. Only working workaround that i found is that you need to detach/attach fragment which you want to update (you need to trigger onCreateView() method of fragment where you build your UI) after i update my Cursor (not CursorAdapter.. you need to update/set adapter in onCreateView() ). This worked for me. Here is code which i use to reattach fragment.

fragmentManager.beginTransaction().detach(frag).attach(frag).commitAllowingStateLoss();

You can also try to remove corresponding listView from layout and that add it to layout again but i got into some issues using this approach.

Upvotes: 0

Thierry Brethes
Thierry Brethes

Reputation: 51

To make it work in all cases (especially with FILL_PARENT layout and orientation change), instead of using a ListView directly, use this class and call invalidateSectionIndexer() after your changed your Adapter.

class MyListView extends ListView {
    public MyListView(Context context) {
        super(context);
    }

    public void invalidateSectionIndexer() {
        // 1. this invalidates the Section Indexer
        super.setFastScrollEnabled(false);
        // Your adapter might be wrapped, e.g. when adding headers/footers.
        ListAdapter adapter = getAdapter();
        BaseAdapter baseAdapter = (adapter instanceof WrapperListAdapter) ?
                (BaseAdapter) ((WrapperListAdapter) adapter).getWrappedAdapter() :
                (BaseAdapter) adapter;
        baseAdapter.notifyDataSetChanged();
        super.setFastScrollEnabled(true);

        // 2. This fixes the android bug of section overlay not positioned correctly.
        int width = getWidth();
        int height = getHeight();
        super.onSizeChanged(width, height, width, height);
    }
}

Upvotes: 5

ol0
ol0

Reputation: 736

Above solutions are ok except for case when width is set to FILL_PARENT. To make them work for this case you should override onSizeChanged like this

@Override
protected void onSizeChanged (int w, int h, int oldw, int oldh)
{
    super.onSizeChanged( w , h , oldw , oldh );
    if ( mInstance.getLayoutParams().width != FrameLayout.LayoutParams.FILL_PARENT )
    {
        mInstance.post( new Runnable()
        {   
            @Override
            public void run()
            {
                mInstance.setLayoutParams( new FrameLayout.LayoutParams( FrameLayout.LayoutParams.FILL_PARENT , FrameLayout.LayoutParams.FILL_PARENT ) );   
            }
        });
    }
}

With this modification size will be ok after changing screen orientation.

Upvotes: 0

Mikael_S
Mikael_S

Reputation: 141

Thought I'd share a ready-made version of the above workaround for a ListActivity:

private boolean FLAG_THUMB_PLUS = false;
private void jiggleWidth() {

    ListView view = getListView();
    if (view.getWidth() <= 0)
        return;

    int newWidth = FLAG_THUMB_PLUS ? view.getWidth() - 1 : view.getWidth() + 1;
    ViewGroup.LayoutParams params = view.getLayoutParams();
    params.width = newWidth;
    view.setLayoutParams( params );

    FLAG_THUMB_PLUS = !FLAG_THUMB_PLUS;
}

Works for me.

Upvotes: 8

Shrikanth Kalluraya
Shrikanth Kalluraya

Reputation: 1119

a small workaround which was suggested by lee.wilmot is

private void jiggleGrid() {

          int newWidth = flag( FLAG_THUMB_PLUS ) ?
FrameLayout.LayoutParams.FILL_PARENT :
                  grid.getWidth() - 1;

          FrameLayout.LayoutParams l = new FrameLayout.LayoutParams(
                          newWidth,
                          FrameLayout.LayoutParams.FILL_PARENT
          );

          grid.setLayoutParams( l );

          toggleFlag( FLAG_THUMB_PLUS );
  }

flag and toggleFlag are some functions.

Call this method after setting setFastScrollEnabled(true);. It worked for me....

Upvotes: 1

Related Questions