web-dev-qa-db-fra.com

SavedInstanceState lors de la restauration d'un fragment à partir de la pile arrière

Puis-je utiliser savedInstanceState() pour enregistrer l'état lors de la suppression d'un fragment, puis restaurer l'état lorsque j'écarte le fragment de la pile arrière? Lorsque je restaure le fragment à partir de la pile arrière, le bundle savedInstanceState est toujours nul.

À l'heure actuelle, le flux d'application est le suivant: fragment créé -> fragment supprimé (ajouté à la pile arrière) -> fragment restauré à partir de la pile arrière (le bundle savedInstanceState est nul).

Voici le code pertinent:

public void onActivityCreated(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    Bundle bundle = getArguments();
    Long playlistId = bundle.getLong(Constants.PLAYLIST_ID);
    int playlistItemId = bundle.getInt(Constants.PLAYLISTITEM_ID);

    if (savedInstanceState == null) {
       selectedVideoNumber = playlistItemId;
    } else {
       selectedVideoNumber = savedInstanceState.getInt("SELECTED_VIDEO");
    }
}

public void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        outState.putInt(Constants.SELECTED_VIDEO, selectedVideoNumber);
    }

Je pense que le problème est que onSavedInstanceState() n'est jamais appelé lorsqu'il est supprimé et ajouté à la pile arrière. Si je ne peux pas utiliser onsavedInstanceState (), existe-t-il un autre moyen de résoudre ce problème?

36
heero

onSaveInstanceState n'est (malheureusement) pas appelé dans la recréation normale d'un back-stack d'un fragment. Consultez http://developer.Android.com/guide/components/fragments.html#Creating et la réponse sur Comment puis-je conserver l'état du fragment lorsqu'il est ajouté à la pile arrière?

6
Eric

J'aime stocker la vue que je renvoie dans onCreateView en tant que variable globale, puis quand je reviens, je vérifie simplement ceci:

if(mBaseView != null) {
        // Remove the view from the parent
        ((ViewGroup)mBaseView.getParent()).removeView(mBaseView);
        // Return it
        return mBaseView;
    }
5
AllDayAmazing

Le problème est que le fragment doit être associé à un Id ou Tag pour que le FragmentManager puisse le suivre.

Il existe au moins 3 façons de procéder:

  1. Dans la disposition xml, déclarez un Id pour votre fragment:

    Android:id=@+id/<Id>
    
  2. Si votre conteneur de fragments View a un Id, utilisez FragmentTransaction :

    FragmentTransaction  add (int containerViewId, Fragment fragment)
    
  3. Si votre fragment n'est associé à aucun View (par exemple un fragment sans tête), donnez-lui un Tag:

    FragmentTransaction  add (Fragment fragment, String tag)
    

Voir aussi cette réponse SO.

3
bcorso

FWIW, j'ai également touché cela, mais dans mon cas, onSaveInstanceState a été appelé correctement et j'ai poussé mes données d'état lorsqu'un nouveau fragment d'activité a été affiché sur le smartphone. Comme vous, onActivityCreated a été appelé avec w/savedInstanceState toujours null. À mon humble avis, je pense que c'est un bug.

J'y ai travaillé en créant un état statique MyApplication et en y plaçant les données pour l'équivalent de "variables globales" ...

0
kenyee