2010-11-15 30 views
11

J'ai une ExpandableListActivity (en utilisant un SimpleCursorTreeAdapter) qui démarre une autre activité lorsque l'utilisateur clique sur un élément-enfant. Lorsque vous appuyez sur le bouton de retour dans la nouvelle activité, tous les éléments de la liste sont à nouveau réduits. Comment puis-je sauvegarder l'état développé de ExpandableListActivity et le restaurer à nouveau.Enregistrer et restaurer l'état déplié/replié d'une ExpandableListActivity

Je l'ai déjà essayé de mise en œuvre onSaveInstanceState() et onRestoreInstanceState() comme ça ...

@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); 
} 

... mais onRestoreInstanceState() ne fait jamais appelé. J'ai aussi essayé de rétablir l'état dans la méthode onCreate(), mais il est pas appelé ainsi:

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

Je suis en train de faire quelque chose de similaire ICI http://stackoverflow.com/questions/10611927/simplecursortreeadapter-and-cursorloader – toobsco42

+0

@ toobsco42 Je ne vois pas comment cela est lié à la question – Tom

+0

Attention à la remise en place de l'adaptateur lors du retour à l'activité précédente. La configuration de l'adaptateur réduira la liste. – jayeffkay

Répondre

11

Malheureusement, l'état expansé revient toujours à chaque fois que l'accent est perdu et n'est pas appelé onCreate() quand il est à nouveau au centre mais onStart(). Ma solution consiste donc à stocker manuellement les ID de tous les éléments développés et à les développer de nouveau dans onStart(). J'ai implémenté une sous-classe de ExpandableListActivity pour réutiliser le comportement.

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; 
    } 
} 

Peut-être que quelqu'un a une meilleure solution.

0

essayer. Il va résoudre le problème, en partie

yourlist.setSaveEnabled(true); 
+0

Malheureusement, cela ne change rien. – Tom

+0

Il fonctionne uniquement pour changer l'orientation d'un écran (si les données de l'adaptateur ne seront pas rechargées après le changement d'orientation d'un écran) – user479211

2

Cela devrait fonctionner

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

La réponse acceptée est complètement inutile. C'est la bonne façon. – JanithaR