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é.
- 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. - 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é.
- Lorsque l'écran pivote, le
onCreate()
méthode deNavigationDrawerFragment
est appelé, en préservant dernier élément sélectionné. - 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).
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
Vous devez vous connecter pour publier un commentaire.
Même si la réponse a déjà été acceptée, permettez-moi de clarifier ce de plus: le "problème" est dans l'Android Studio modèle. Le problème, comme l'a souligné Edmund, qui est dans le Tiroir de Navigation appeler le menu lorsque recréé, donc re-appeler le Fragment.
Pour résoudre ce problème, j'ai fait cette légère modification sur le NavigationDrawerFragment.java fichier proposé par Android Studio.
Original:
Nouvelle:
Viens de perdre une demi-journée de production. Espérons qu'il peut aider quelqu'un d'autre.
Je vous remercie donc beaucoup beaucoup
Génial! C'est juste ce que je cherchais. Je me demande pourquoi pré-construit de navigation tiroir n'est pas totalement prêt pour des changements de configuration. Il a aidé! Merci!
OriginalL'auteur Miguel El Merendero
Tel que mis à jour dans la question, c'est résolu et merci encore à @Luksprog pour souligner ce que j'ai négligé.
Le comportement de
Fragment
fait aligne avecActivity
classes.Voici la cause de mon problème:
NavigationDrawerFragment
classe.onCreate()
méthode deNavigationDrawerFragment
est appelé, en préservant dernier élément sélectionné.NavigationDrawerFragment
appelleraselectItem()
de nouveau, ce qui déclenche mon élément de menu sélectionné gestionnaire. Cela provoque laListFragment
être remplacé.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, ou en désactivant cette
selectItem()
appel.OriginalL'auteur Edmund Tam
Vous n'avez pas besoin de gérer sur savedInstanceState. Parce que tous les fragments stockés dans un fragment de la crèche (comme tableau de fragments) et lorsque les changements d'orientation de l'activité détruit mais fragment gestionnaire de toujours tenir tous les fragments qui a été ajouté avant. Donc, vous avez juste besoin de vérifier si le fragment a déjà été ajouté.
OriginalL'auteur Dmytro Ubogyi
Essayez d'utiliser
onCreateView()
ici au lieu deonCreate()
, qui est spécifique à des Fragments et pourrait faire une différence.Remplacer
onSaveInstanceState()
pour stocker votre état, et de les récupérer dansonCreateView()
à l'aide desavedInstanceState.get*()
. C'est comment nous le faisons dans nos applications, et cela devrait fonctionner. @Ari dessus, assurez-vous d'appelersuper.onSaveInstanceState(outState)
.OriginalL'auteur sulai
Dans AndroidManifest.xml ajouter
OriginalL'auteur rad