Fragment recréé à chaque fois après le changement d'orientation, incapable de restaurer l'état

Mise à jour: Il s'avère que le problème est ailleurs. Merci @Luksprog pour souligner ce que j'ai négligé.

  1. Le projet est créé à l'aide d'Android Studio de navigation du tiroir modèle. Le tiroir est mis en œuvre dans le NavigationDrawerFragment classe.
  2. Le fragment de la tenue de la vue pager est ajouté lorsqu'un élément particulier dans le tiroir est sélectionné. Le code est mis en œuvre ma maison de l'activité.
  3. Lorsque l'écran pivote, le onCreate() méthode de NavigationDrawerFragment est appelé, en préservant dernier élément sélectionné.
  4. Et voici ce qui s'est passé - à la récréation, NavigationDrawerFragment appellera selectItem() de nouveau, ce qui déclenche mon élément de menu sélectionné gestionnaire. Cela provoque la ListFragment restauré par Android.

Cela peut être évité par la vérification de l'élément de menu actif dans mon menu de sélection du code du gestionnaire.


Je veux conserver la dernière page de visualisation de l'indice de la ViewPager lorsque l'activité est recréée par quelque raison que ce soit, par exemple, changement d'orientation.

La ViewPager est dans un Fragment (nommé ListFragment), qui est rattaché à une activité. Je suis l'aide de la compatibilité de la bibliothèque, de sorte que le fragment est une sous-classe de android.support.v4.app.Fragment.

J'ai pensé que cela pourrait se faire en remplaçant la onSaveInstanceState() méthode et ajouter logique approprié dans onCreate(), comme dessus décrite dans le doc:

De traiter correctement un redémarrage, il est important que votre activité
restaure son état précédent par le biais de l'Activité normale du cycle de vie, dans
qui Android appels onSaveInstanceState() avant qu'il ne détruise votre
l'activité de sorte que vous pouvez enregistrer des données sur l'état de l'application. Vous
pouvez ensuite restaurer l'état au cours de onCreate() ou
onRestoreInstanceState().

Mais la situation semble différente pour les fragments. L'index de la page peut être restauré correctement quand je naviguer à partir de cette ListFragment à l'autre de l'activité et de la touche "retour". Cependant, quand je tourne mon appareil, l'index de la page est perdu.

J'ai ajouté quelques traces de voir quel est le problème. D'après le journal, j'ai trouvé que, bien que onSaveInstanceState() de la ListFragment(je vais l'appeler ListFragment A) est appelé correctement, ce Fragment de classe n'est plus affiché dans l'activité. Lorsque l'orientation a changé et l'activité est recréée, Android appels onSaveInstanceState() suivie par onDetach() à se détacher de ce fragment. Puis Android crée une nouvelle instance de ListFragment (je vais l'appeler ListFragment B) et le joindre à la nouvelle, la rotation de l'activité. Cette ListFragment B a un vide savedInstanceState transmis au constructeur, et donc la dernière page de l'index (et n'importe quelle configuration en savedInstanceState du Fragment A) est perdu.

En fait, une nouvelle instance de ListFragment sera créé à chaque fois qu'une rotation de l'écran se produit, mais il semble que les anciens ne seront pas détruits. Je vois des journaux comme ci-dessous lorsque je tourne l'appareil:

D/ListFragment [1110257048] onSaveInstanceState() called, storing last page index 3
D/ListFragment [1109835992] onSaveInstanceState() called, storing last page index 0
D/ListFragment [1108826176] onSaveInstanceState() called, storing last page index 0
D/ListFragment [1108083096] onSaveInstanceState() called, storing last page index 0
D/ListFragment [1106541040] onSaveInstanceState() called, storing last page index 0
D/ListFragment [1108316656] onSaveInstanceState() called, storing last page index 0
D/ListFragment [1109134136] onSaveInstanceState() called, storing last page index 0
D/ListFragment [1108630992] onSaveInstanceState() called, storing last page index 0
D/ListFragment [1108592888] onSaveInstanceState() called, storing last page index 0
D/ListFragment [1109729064] onSaveInstanceState() called, storing last page index 0
D/ListFragment [1110257048] onDestroy()
D/ListFragment [1110257048] onDetach()
D/ListFragment [1109835992] onDestroy()
D/ListFragment [1109835992] onDetach()
D/ListFragment [1108826176] onDestroy()
D/ListFragment [1108826176] onDetach()
D/ListFragment [1108083096] onDestroy()
D/ListFragment [1108083096] onDetach()
D/ListFragment [1106541040] onDestroy()
D/ListFragment [1106541040] onDetach()
D/ListFragment [1108316656] onDestroy()
D/ListFragment [1108316656] onDetach()
D/ListFragment [1109134136] onDestroy()
D/ListFragment [1109134136] onDetach()
D/ListFragment [1108630992] onDestroy()
D/ListFragment [1108630992] onDetach()
D/ListFragment [1108592888] onDestroy()
D/ListFragment [1108592888] onDetach()
D/ListFragment [1109729064] onDestroy()
D/ListFragment [1109729064] onDetach()
D/ListFragment [1110903656] onAttach()
D/ListFragment [1110903656] onCreate()
D/ListFragment [1110903656] savedInstanceState is not NULL.
D/ListFragment [1110903656] Retrieving last page index 3
D/ListFragment [1110905248] onAttach()
D/ListFragment [1110905248] onCreate()
D/ListFragment [1110905248]   savedInstanceState is not NULL.
D/ListFragment [1110905248]   Retrieving last page index 0
D/ListFragment [1110906440] onAttach()
D/ListFragment [1110906440] onCreate()
D/ListFragment [1110906440]   savedInstanceState is not NULL.
D/ListFragment [1110906440]   Retrieving last page index 0
D/ListFragment [1110907632] onAttach()
D/ListFragment [1110907632] onCreate()
D/ListFragment [1110907632]   savedInstanceState is not NULL.
D/ListFragment [1110907632]   Retrieving last page index 0
D/ListFragment [1110908824] onAttach()
D/ListFragment [1110908824] onCreate()
D/ListFragment [1110908824]   savedInstanceState is not NULL.
D/ListFragment [1110908824]   Retrieving last page index 0
D/ListFragment [1110910016] onAttach()
D/ListFragment [1110910016] onCreate()
D/ListFragment [1110910016]   savedInstanceState is not NULL.
D/ListFragment [1110910016]   Retrieving last page index 0
D/ListFragment [1110911208] onAttach()
D/ListFragment [1110911208] onCreate()
D/ListFragment [1110911208]   savedInstanceState is not NULL.
D/ListFragment [1110911208]   Retrieving last page index 0
D/ListFragment [1110912400] onAttach()
D/ListFragment [1110912400] onCreate()
D/ListFragment [1110912400]   savedInstanceState is not NULL.
D/ListFragment [1110912400]   Retrieving last page index 0
D/ListFragment [1110913592] onAttach()
D/ListFragment [1110913592] onCreate()
D/ListFragment [1110913592]   savedInstanceState is not NULL.
D/ListFragment [1110913592]   Retrieving last page index 0
D/ListFragment [1110914784] onAttach()
D/ListFragment [1110914784] onCreate()
D/ListFragment [1110914784]   savedInstanceState is not NULL.
D/ListFragment [1110914784]   Retrieving last page index 0
D/HomeActivity fragment updated
D/ListFragment [1110914784] onCreateView()
D/ListFragment [1111031048] onAttach()
D/HomeActivity Fragment attached.
D/ListFragment [1111031048] onCreate()
D/ListFragment [1111031048]   savedInstanceState is NULL.
D/ListFragment [1111031048] onCreateView()
D/ListFragment [1111031048] onResume(), restoring page index 0

C'est le journal, après j'ai fait tourner l'écran pendant environ 10 fois. Le nombre dans la balise est des classes hashCode(). Lignes ci-dessus montre que onSaveInstanceState() et onCreate() précédemment créé fragments encore appelée, même après qu'ils sont remplacées par les plus récentes (1111031048).

Remarque que je n'a pas appel setRetainInstance() dans le fragment de la classe. En fait, j'ai essayé les deux setRetainInstance(false) et setRetainInstance(true) mais ça ne change rien.

Ai-je fait quelque chose de mal ici? Je peux comprendre que ListFragment doit être recréée, mais pourquoi savedInstanceState est nulle? Et si c'est le comportement attendu, quelle est la bonne façon de résoudre mon besoin, c'est à dire en gardant l'index de la page lorsque des modifications de configuration?

Il devrait être possible de faire l'index de la page statique variable de classe, mais je ne sais pas si c'est réellement résoudre le problème, ou tout simplement de les cacher (parce que je sens l'odeur de fuite de mémoire dans le journal ci-dessus).

Appelez-vous super sur tous les surdéfini de l'activité et de fragments de méthodes (comme onCreate, onSaveInstanceState) et ainsi de suite?
Êtes-vous sûr que votre fragment qui détient le ViewPager n'est pas de l'ajouter à nouveau(par erreur) par votre code après la rotation, en remplacement de l'existant?
Vous avez absolument raison. Je suis trop concentré sur le fragment, et négligé cette partie. Je mettrai à jour mon post. Merci beaucoup!
Vous devriez poster une réponse et de l'accepter(pour vos autres questions que bien si vous avez une réponse adéquate) de sorte que la question apparaîtra comme résolu.
Merci. Je n'étais pas sûr si c'est approprié pour moi de répondre à ma propre question (et le marquer comme réponse) pour une erreur stupide comme ça, mais j'ai suivi vos conseils et j'espère qu'il pourrait bientôt aider quelqu'un.

OriginalL'auteur Edmund Tam | 2014-01-24