2010-11-15 72 views
11

我有一个ExpandableListActivity(使用SimpleCursorTreeAdapter),它在用户单击子元素时启动另一个活动。在新活动中按下后退按钮时,所有列表项都会再次折叠。如何保存ExpandableListActivity的展开状态并重新恢复。保存并恢复ExpandableListActivity的展开/折叠状态

我已经尝试过的onSaveInstanceState实现的()和onRestoreInstanceState()这样的...

@Override 
protected void onSaveInstanceState(Bundle outState) { 
    super.onSaveInstanceState(outState); 
    Parcelable listState = getExpandableListView().onSaveInstanceState(); 
    outState.putParcelable("ListState", listState); 
} 


@Override 
protected void onRestoreInstanceState(Bundle state) { 
    super.onRestoreInstanceState(state); 
    Parcelable listState = state.getParcelable("ListState"); 
    getExpandableListView().onRestoreInstanceState(listState); 
} 

...但onRestoreInstanceState()获取从来没有所谓。我也尝试在onCreate()方法中恢复状态,但它不会被调用:

if (savedInstanceState != null) { 
    Parcelable listState = savedInstanceState.getParcelable("ListState"); 
    getExpandableListView().onRestoreInstanceState(listState); 
} 
+0

我在做类似的位置http://stackoverflow.com/questions/10611927/simplecursortreeadapter-and-cursorloader – toobsco42 2012-05-16 07:22:12

+0

@ toobsco42我不明白这是怎么涉及到的东西问题 – Tom 2012-05-16 08:39:38

+0

当返回到先前的活动时,请小心再次设置适配器。重新设置适配器将折叠列表。 – jayeffkay 2013-05-08 10:30:25

回答

11

不幸的是扩张状态总是复位每当焦点丢失的onCreate(),当它再次获得焦点,但在onStart()不被调用。所以我现在的解决方法是手动存储所有扩展项目的ID并再次将它们展开到onStart()中。我实现了ExpandableListActivity的子类来重用行为。

public class PersistentExpandableListActivity extends ExpandableListActivity { 
    private long[] expandedIds; 

    @Override 
    protected void onStart() { 
     super.onStart(); 
     if (this.expandedIds != null) { 
      restoreExpandedState(expandedIds); 
     } 
    } 

    @Override 
    protected void onStop() { 
     super.onStop(); 
     expandedIds = getExpandedIds(); 
    } 

    @Override 
    protected void onSaveInstanceState(Bundle outState) { 
     super.onSaveInstanceState(outState); 
     this.expandedIds = getExpandedIds(); 
     outState.putLongArray("ExpandedIds", this.expandedIds); 
    } 

    @Override 
    protected void onRestoreInstanceState(Bundle state) { 
     super.onRestoreInstanceState(state); 
     long[] expandedIds = state.getLongArray("ExpandedIds"); 
     if (expandedIds != null) { 
      restoreExpandedState(expandedIds); 
     } 
    } 

    private long[] getExpandedIds() { 
     ExpandableListView list = getExpandableListView(); 
     ExpandableListAdapter adapter = getExpandableListAdapter(); 
     if (adapter != null) { 
      int length = adapter.getGroupCount(); 
      ArrayList<Long> expandedIds = new ArrayList<Long>(); 
      for(int i=0; i < length; i++) { 
       if(list.isGroupExpanded(i)) { 
        expandedIds.add(adapter.getGroupId(i)); 
       } 
      } 
      return toLongArray(expandedIds); 
     } else { 
      return null; 
     } 
    } 

    private void restoreExpandedState(long[] expandedIds) { 
     this.expandedIds = expandedIds; 
     if (expandedIds != null) { 
      ExpandableListView list = getExpandableListView(); 
      ExpandableListAdapter adapter = getExpandableListAdapter(); 
      if (adapter != null) { 
       for (int i=0; i<adapter.getGroupCount(); i++) { 
        long id = adapter.getGroupId(i); 
        if (inArray(expandedIds, id)) list.expandGroup(i); 
       } 
      } 
     } 
    } 

    private static boolean inArray(long[] array, long element) { 
     for (long l : array) { 
      if (l == element) { 
       return true; 
      } 
     } 
     return false; 
    } 

    private static long[] toLongArray(List<Long> list) { 
     long[] ret = new long[list.size()]; 
     int i = 0; 
     for (Long e : list) 
      ret[i++] = e.longValue(); 
     return ret; 
    } 
} 

虽然可能有人有更好的解决方案。

0

试试这个。这将解决这个问题,一方面

yourlist.setSaveEnabled(true); 
+0

不幸的是,这并没有改变任何东西。 – Tom 2010-11-15 14:05:10

+0

仅适用于屏幕更改方向(如果在更改屏幕方向后适配器的数据不会重新加载) – user479211 2010-11-15 14:29:47

2

这应该工作

Parcelable state = exercisesList.onSaveInstanceState(); 
exercisesList.setAdapter(....); 
exercisesList.onRestoreInstanceState(state); 
+1

接受的答案是完全不必要的。这是正确的方法。 – JanithaR 2017-08-10 09:35:33