Is there a way to prevent the listview from scrolling to its top position when its adapter's data is changed?

前端 未结 4 1064
無奈伤痛
無奈伤痛 2020-12-09 03:43

I\'m having a bit of trouble preserving the scroll position of a list view when changing it\'s adapter\'s data.

What I\'m currently doing is to create a custom Array

相关标签:
4条回答
  • 2020-12-09 04:09

    In your Expandable/List Adapter, put this method

    public void refresh(List<MyDataClass> dataList) {
        mDataList.clear();
        mDataList.addAll(events);
        notifyDataSetChanged();
    }
    

    And from your activity, where you want to update the list, put this code

    if (mDataListView.getAdapter() == null) {
        MyDataAdapter myDataAdapter = new MyDataAdapter(mContext, dataList);
        mDataListView.setAdapter(myDataAdapter);
    } else {
        ((MyDataAdapter)mDataListView.getAdapter()).refresh(dataList);
    }
    

    In case of Expandable List View, you will use mDataListView.getExpandableListAdapter() instead of mDataListView.getAdapter()

    0 讨论(0)
  • 2020-12-09 04:14

    Check out: Maintain/Save/Restore scroll position when returning to a ListView

    Use this to save the position in the ListView before you call .clear(), .addAll(), and . notifyDataSetChanged().

    int index = mList.getFirstVisiblePosition();
    View v = mList.getChildAt(0);
    int top = (v == null) ? 0 : v.getTop();
    

    After updating the ListView adapter, the Listview's items will be changed and then set the new position:

    mList.setSelectionFromTop(index, top);
    

    Basically you can save you position and scroll back to it, save the ListView state or the entire application state.

    Other helpful links:

    Save Position: How to save and restore ListView position in Android

    Save State: Android ListView y position

    Regards,

    Please let me know if this helps!

    0 讨论(0)
  • 2020-12-09 04:19

    As you pointed out yourself, the call to 'clear()' causes the position to be reset to the top.

    Fiddling with scroll-position, etc. is a bit of a hack to get this working.

    If your CustomListAdapter subclasses from ArrayAdapter, this could be the issue:

    The call to clear(), calls 'notifyDataSetChanged()'. You can prevent this:

    mListAdapter.setNotifyOnChange(false); // Prevents 'clear()' from clearing/resetting the listview
    mListAdapter.clear();
    mListAdapter.addAll(data.items);
    // note that a call to notifyDataSetChanged() implicitly sets the setNotifyOnChange back to 'true'!
    // That's why the call 'setNotifyOnChange(false) should be called first every time (see call before 'clear()').
    mListAdapter.notifyDataSetChanged(); 
    

    I haven't tried this myself, but try it :)

    0 讨论(0)
  • 2020-12-09 04:19

    There is one more use-case I came across recently (Android 8.1) - caused by bug in Android code. If I use mouse-wheel to scroll list view - consecutive adapter.notifyDataSetChanged() resets scroll position to zero. Use this workaround until bug gets fixed in Android

            listView.onTouchModeChanged(true); // workaround
            adapter.notifyDataSetChanged();
    

    More details is here: https://issuetracker.google.com/u/1/issues/130103876

    0 讨论(0)
提交回复
热议问题