2010-11-15 95 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