How to save and restore the state of an ExpandableListView in Android?

后端 未结 4 940
醉酒成梦
醉酒成梦 2021-01-06 12:45

Is it possible to save and restore the state (which items are collapsed and which not) of an ExpandableListView in Android?

If it is possible, how can I do that?

相关标签:
4条回答
  • 2021-01-06 12:52

    I came across this very same question and found a better answer. I have a fragment and use the onSaveInstanceState and onViewStateRestored to save and restore the ExpandableListView.

    Here I save the state of the list

    @Override
    public void onSaveInstanceState( @NonNull Bundle outState )
    {
        super.onSaveInstanceState( outState );
    
        ExpandableListView expandable = getView() != null ? getView().findViewById( R.id.expandable ) : null;
        if( expandable != null )
        {
            int groupsCount = expandable.getExpandableListAdapter()
                                        .getGroupCount();
            boolean[] groupExpandedArray = new boolean[groupsCount];
            for( int i = 0; i < groupsCount; i += 1 )
            {
                groupExpandedArray[i] = expandable.isGroupExpanded( i );
            }
            outState.putBooleanArray( "groupExpandedArray", groupExpandedArray );
            outState.putInt( "firstVisiblePosition", expandable.getFirstVisiblePosition() );
        }
    }
    

    And here I restore it when it is needed

    @Override
    public void onViewStateRestored( @Nullable Bundle savedInstanceState )
    {
        super.onViewStateRestored( savedInstanceState );
        if( savedInstanceState != null )
        {
            boolean[]          groupExpandedArray   = savedInstanceState.getBooleanArray( "groupExpandedArray" );
            int                firstVisiblePosition = savedInstanceState.getInt( "firstVisiblePosition", -1 );
            ExpandableListView expandable           = getView() instanceof ViewGroup ? getView().findViewById( R.id.expandable ) : null;
            if( expandable != null && groupExpandedArray != null )
            {
                for( int i = 0; i < groupExpandedArray.length; i++ )
                {
                    if( groupExpandedArray[i] )
                        expandable.expandGroup( i );
                }
                if( firstVisiblePosition >= 0 )
                    expandable.setSelection( firstVisiblePosition );
            }
        }
    }
    
    0 讨论(0)
  • 2021-01-06 13:01

    a simpler way could be, if you're using setOnGroupClickListner and setOnChildClickListener just keep the last selected ChildPosition and GroupPositin integer and later on check it and respond properly,

    if (childPosition > 0) {
        mExpandableList.expandGroup(groupPositin);
    }
    mExpandableList.setItemChecked(groupPositin + childPosition , true);
    

    you just need to remember set childPosition to 0 in your setOnGroupListener method.

    0 讨论(0)
  • 2021-01-06 13:05

    I iterate through the groups and save the state of them all:

    int numberOfGroups = MyExpandableListViewAdapter.getGroupCount();
    boolean[] groupExpandedArray = new boolean[numberOfGroups];
      for (int i=0;i<numberOfGroups;i++)
        groupExpandedArray[i] = MyExpandableListView.isGroupExpanded(i);
    

    Then for restore the state:

    for (int i=0;i<groupExpandedArray.length;i++)
      if (groupExpandedArray[i] == true)
        MyExpandableListView.expandGroup(i);
    

    I don't understand what you mean by how to access the ListView in onPause() / onResume(), it should be accessible from there if you store the ListView object as a member of the activity class.

    0 讨论(0)
  • 2021-01-06 13:11

    Improving Floaf's answer: declare

     public static int firstVisiblePosition=0;
    

    on Pause

    int numberOfGroups = MyExpandableListViewAdapter.getGroupCount();
    boolean[] groupExpandedArray = new boolean[numberOfGroups];
    for (int i=0;i<numberOfGroups;i++){
        groupExpandedArray[i] = MyExpandableListView.isGroupExpanded(i);
    }
    firstVisiblePosition = MyExpandableListView.getFirstVisiblePosition();
    

    onResume

    for (int i=0;i<groupExpandedArray.length;i++){
      if (groupExpandedArray[i] == true)
          MyExpandableListView.expandGroup(i);
    }
    MyExpandableListView.setSelection(firstVisiblePosition );
    

    This will not only restore each group's state but it will also scroll to the childView that was viewed when activity paused.

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