How to preserve scroll position in an ExpandableListView

后端 未结 4 468
走了就别回头了
走了就别回头了 2021-01-31 21:44

in my app I have a class derived from ExpandableListActivity. When I scroll the contents, and then change phone orientation or edit an item and then go back to the list, the ori

4条回答
  •  温柔的废话
    2021-01-31 22:08

    After a few experiments I have come to a satisfactory solution, which also preserves the fine scroll position of the top visible item.

    As a matter of fact, three different pieces of information need to be saved and restored: the list state (e.g. which groups are expanded), the index of the first visible item, and its fine scroll position.

    Unfortunately, it seems that only the first one is saved by the onSaveInstanceState method of the expandable list view, so the other two need to be saved separately. This is different from a non expandable list view, where it appears the onSaveInstanceState method saves all the information needed to properly restore state and position of the list (on this subject, see Maintain/Save/Restore scroll position when returning to a ListView).

    Here are the code snippets; on top of the ExpandableListActivity-derived class:

    private static final String LIST_STATE_KEY = "listState";
    private static final String LIST_POSITION_KEY = "listPosition";
    private static final String ITEM_POSITION_KEY = "itemPosition";
    
    private Parcelable mListState = null;
    private int mListPosition = 0;
    private int mItemPosition = 0;
    

    Then, some overrides:

    protected void onRestoreInstanceState(Bundle state) {
        super.onRestoreInstanceState(state);
    
        // Retrieve list state and list/item positions
        mListState = state.getParcelable(LIST_STATE_KEY);
        mListPosition = state.getInt(LIST_POSITION_KEY);
        mItemPosition = state.getInt(ITEM_POSITION_KEY);
    }
    
    protected void onResume() {
        super.onResume();
    
        // Load data from DB and put it onto the list
        loadData();
    
        // Restore list state and list/item positions
        ExpandableListView listView = getExpandableListView();
        if (mListState != null)
            listView.onRestoreInstanceState(mListState);
        listView.setSelectionFromTop(mListPosition, mItemPosition);
    }
    
    protected void onSaveInstanceState(Bundle state) {
        super.onSaveInstanceState(state);
    
        // Save list state
        ExpandableListView listView = getExpandableListView();
        mListState = listView.onSaveInstanceState();
        state.putParcelable(LIST_STATE_KEY, mListState);
    
        // Save position of first visible item
        mListPosition = listView.getFirstVisiblePosition();
        state.putInt(LIST_POSITION_KEY, mListPosition);
    
        // Save scroll position of item
        View itemView = listView.getChildAt(0);
        mItemPosition = itemView == null ? 0 : itemView.getTop();
        state.putInt(ITEM_POSITION_KEY, mItemPosition);
    }
    

    This works fine on my Froyo device.

提交回复
热议问题