Dans Android, un fragment (par exemple FragA
) est ajouté à la backstack et un autre fragment (par exemple FragB
) arrive en haut. Maintenant, en frappant en arrière FragA
vient au sommet et le onCreateView()
est appelé. Maintenant, j'avais FragA
dans un état particulier avant d' FragB
être poussé dessus.
Ma question est de savoir comment puis-je restaurer FragA
son état antérieur? Existe-t-il un moyen de sauvegarder l'état (comme par exemple dans un bundle) et si oui, quelle méthode dois-je remplacer?
la source
onSaveInstanceState
n'est appelée que lorsque son activité correspondante s'arrête également.Les fragments ne
onSaveInstanceState(Bundle outState)
seront jamais appelés à moins que l'activité du fragment ne l'appelle sur lui-même et les fragments attachés. Ainsi, cette méthode ne sera pas appelée jusqu'à ce que quelque chose (généralement une rotation) force l'activitéSaveInstanceState
et la restaure plus tard. Mais si vous n'avez qu'une seule activité et un grand ensemble de fragments à l'intérieur (avec une utilisation intensive dereplace
) et que l'application ne s'exécute que dans une seule activité d'orientation, elleonSaveInstanceState(Bundle outState)
peut ne pas être appelée pendant longtemps.Je connais trois solutions de contournement possibles.
La première:
utilisez les arguments de fragment pour contenir des données importantes:
La seconde, mais de manière moins pédant - variables de maintien dans singletons
Le troisième - ne pas
replace()
fragmenter maisadd()
/show()
/hide()
eux à la place.la source
Fragment.onSaveInstanceState()
on n'a jamais été appelé. Enregistrez simplement vos propres données dans l'argument, y compris les éléments de la vue liste ou simplement leurs identifiants (si vous avez un autre gestionnaire de données centralisé). Pas besoin d'enregistrer la position de la vue de liste - qui a été enregistrée et restaurée automatiquement.String persistentVariable = mySavedInstanceState.getString(PERSISTENT_VARIABLE_BUNDLE_KEY);
est toujoursnull
. Quel est le problème?getArguments()
est DEFINITIVEMENT la voie à suivre, y compris les fragments imbriqués dans un ViewPager. J'utilise 1 activité et échangez de nombreux fragments in / out, et cela fonctionne parfaitement. Voici un test simple pour vous permettre de vérifier toute solution proposée: 1) passer du fragment A au fragment B; 2) changer l'orientation de l'appareil deux fois; 3) appuyez sur le bouton de retour de l'appareil.setArguments(new Bundle());
écrasé l'ancien Bundle. Assurez-vous donc d'avoir créé le fragment une seule fois, puis utilisez cette instance au lieu d'en créer une à chaque fois.Notez simplement que si vous travaillez avec des fragments à l'aide de ViewPager, c'est assez facile. Il vous suffit d'appeler cette méthode:
setOffscreenPageLimit()
.Accordign aux docs:
Problème similaire ici
la source
Gonflez simplement votre View pour une fois.
suit Exemple:
}
la source
Fragment
réfère à sa vue racine ne fera pas cela. Alors que la référence par certains éléments GC-root sera, comme la propriété statique globale, une variable de thread non-ui. UneFragment
instance n'est pas GC-root, elle peut donc être récupérée. Il en sera de même pour sa vue racine.J'ai travaillé avec un problème très similaire à celui-ci. Comme je savais que je reviendrais fréquemment à un fragment précédent, j'ai vérifié si le fragment
.isAdded()
était vrai, et si oui, plutôt que de faire un,transaction.replace()
je fais juste untransaction.show()
. Cela empêche le fragment d'être recréé s'il est déjà sur la pile - aucune sauvegarde d'état n'est nécessaire.Une autre chose à garder à l'esprit est que, bien que cela préserve l'ordre naturel des fragments eux-mêmes, vous devrez peut-être gérer l'activité elle-même détruite et recréée lors du changement d'orientation (de configuration). Pour contourner ce problème dans AndroidManifest.xml pour votre nœud:
Dans Android 3.0 et supérieur, le
screenSize
est apparemment requis.Bonne chance
la source
android:configChanges=everythinYouCanThinkOf|moreThingsYouFoundOnTheInternets
votre manifeste. Apprenez plutôt à enregistrer et à restaurer l'état, par exemple à partir d'ici: speakerdeck.com/cyrilmottierLa meilleure solution que j'ai trouvée est ci-dessous:
onSavedInstanceState (): toujours appelé à l'intérieur du fragment lorsque l'activité va s'arrêter (déplacer l'activité de l'une à l'autre ou modifier la configuration). Donc, si nous appelons plusieurs fragments sur la même activité, nous devons utiliser l'approche suivante:
Utilisez OnDestroyView () du fragment et enregistrez l'objet entier dans cette méthode. Then OnActivityCreated (): Vérifiez que si l'objet est nul ou non (car cette méthode appelle à chaque fois). Maintenant, restaurez l'état d'un objet ici.
Cela fonctionne toujours!
la source
si vous gérez les changements de configuration dans votre activité de fragment spécifiée dans le manifeste Android comme ceci
alors le
onSaveInstanceState
du fragment ne sera pas invoqué et l'savedInstanceState
objet sera toujours nul.la source
je ne pense pas que ce
onSaveInstanceState
soit une bonne solution. il ne sert qu'à une activité qui avait été déstockée.Depuis Android 3.0, le Fragmen a été gestionnaire par FragmentManager, la condition est: une activité de cartographie de nombreux fragments, lorsque le fragment est ajouté (pas remplacé: il sera recréé) dans backStack, la vue sera déstockée. une fois de retour au dernier, il s'affichera comme avant.
Je pense donc que le fragmentManger et la transaction sont assez bons pour le gérer.
la source
J'ai utilisé une approche hybride pour les fragments contenant une vue de liste. Cela semble être performant puisque je ne remplace pas le fragment actuel, mais ajoute plutôt le nouveau fragment et cache le fragment actuel. J'ai la méthode suivante dans l'activité qui héberge mes fragments:
J'utilise cette méthode dans mon fragment (contenant la vue de liste) chaque fois qu'un élément de liste est cliqué / tapé (et donc j'ai besoin de lancer / afficher le fragment de détails):
getFragmentTags()
renvoie un tableau de chaînes que j'utilise comme balises pour différents fragments lorsque j'ajoute un nouveau fragment (voirtransaction.add
méthode dans laaddFragment
méthode ci-dessus).Dans le fragment contenant la vue liste, je fais ceci dans sa méthode onPause ():
Puis dans onCreateView du fragment (en fait dans une méthode qui est invoquée dans onCreateView), je restaure l'état:
la source
En fin de compte, après avoir essayé plusieurs de ces solutions compliquées, car je n'avais besoin que de sauvegarder / restaurer une seule valeur dans mon Fragment (le contenu d'un EditText), et bien que ce ne soit peut-être pas la solution la plus élégante, créer une SharedPreference et stocker mon état là a travaillé pour moi
la source
Un moyen simple de conserver les valeurs des champs dans différents fragments d'une activité
Créer les instances de fragments et ajouter au lieu de remplacer et supprimer
Ensuite, affichez et masquez simplement les fragments au lieu de les ajouter et de les supprimer à nouveau
;
la source
la source