2013-05-25 3 views
3

Dans mon FragmentActivity j'utilise plusieurs fragments. Lorsque la configuration est modifiée (en rotation), le système détruit et recrée chaque fragment.
J'essaie d'utiliser ces fragments recrééesCertains fragments sont perdus à la rotation

mFragment = getSupportFragmentManager().findFragmentById(R.id.fragment_frame); 

et le mettre à la disposition nouvelle

getSupportFragmentManager().beginTransaction() 
    .replace(R.id.fragment_frame, mFragment)  
    .commit(); 

mais rencontrer un comportement étrange: plusieurs fragments sont perdus. ils ne sont plus affichés sur l'écran. à leur place est vide.
Bien que les journaux montrent que les fragments sont bien re-crée, mais montre en outre que le fragment est de nouveau détruit, à nouveau créé et détruit à nouveau.

Je construis un projet de test pour le problème du spectacle plus clairement et sans cosse.
et que des résultats tangibles (réputation ne suffit pas d'insérer des images)
Activity started picture
Activity rotated picture

A, B, C, D est un fragments
Comme vous pouvez le voir après la configuration a changé certains fragments sont perdus (B, D)

me dire ce que je fais mal

est ici le code pour aider (Edit: code pousser à GitHub pour pour le rendre plus facile d'essayer)

https:// github.com/nailgilaziev/TestFragmentsRetain 

p/s désolé liens

ici log chat après je tourne dispositif

MainActivity: onPause Activity 
MainActivity: onStop Activity 
MainActivity: onDestroy Activity 
A: onDestroyview 
A: onDestroy 
B: onDestroyview 
B: onDestroy 
C: onDestroyview 
C: onDestroy 
D: onDestroyview 
D: onDestroy 
MainActivity: onCreate Activity 
A: onCreate 
B: onCreate 
C: onCreate 
D: onCreate 
MainActivity: replaced 
MainActivity: onStart Activity 
A: onCreateView 
B: onCreateView 
C: onCreateView 
D: onCreateView 

<--before this point all fine and then strange behavior began 
for the lost fragments(B,D) are performed unnecessary calls--> 

B: onDestroyview 
B: onDestroy 
D: onDestroyview 
D: onDestroy 
D: onCreate 
D: onCreateView 
MainActivity: onResume Activity 
+0

Vérifiez ma réponse ci-dessous et faites un essai, n'oubliez pas de upvote si ma solution fonctionne pour vous :): http://stackoverflow.com/questions/16630502/fragmentadapter-doesnt-hold-the-good- reference-of-the-fragment/16630812 # 16630812 –

+0

@Yann Non, malheureusement, cela n'aide pas. 'setRetainInstance (true)' stocke uniquement l'objet en mémoire, mais n'est toujours pas ajouté dans la nouvelle présentation. Je vais ajouter un chat sur la question d'origine, peut-être que cela aidera – nail

Répondre

7

En brisant votre problème tel qu'il ya deux fragments à la place de quatre, vous verrez que onCreateView est appelée plusieurs fois sur le même Fragment lorsque l'orientation change. C'est une indication que le même fragment est ajouté/créé plus d'une fois.

Fondamentalement, lorsque l'orientation change, vos fragments seront automatiquement rattachés de sorte qu'il n'est pas nécessaire d'effectuer un FragmentTransaction chaque fois que onCreate(Bundle) est appelée.

Ce que vous devez faire à la place ... onCreate(Bundle) est

  1. Null vérifier l'savedInstanceState Bundle qui est passé dans onCreate(Bundle). - Si un changement d'orientation se produit, onCreate(Bundle) est invoqué à nouveau et l'ensemble savedInstanceState devient non nul. FragmentActivity enregistre les données dans onSaveInstanceState(Bundle) avant de les recréer. Si savedInstanceState est nul, créez vos fragments et attachez-les via FragmentTransaction. Sinon, ne faites rien.

En résumé, votre code révisé devrait ressembler à ce qui suit ...

FragmentManager fm = getSupportFragmentManager(); 
if(savedInstanceState == null) { 
    fm.beginTransaction() 
      .replace(R.id.a, new A()) 
      .replace(R.id.b, new B()) 
      .replace(R.id.c, new C()) 
      .replace(R.id.d, new D()) 
      .commit(); 
} 
else { 
    a = fm.findFragmentById(R.id.a); 
    b = fm.findFragmentById(R.id.b); 
    c = fm.findFragmentById(R.id.c); 
    d = fm.findFragmentById(R.id.d); 
} 

En outre, note côté, le faisceau savedInstanceState dans la méthode onCreate(Bundle) d'un Fragment sera toujours être nul, sauf si vous enregistrez quelque chose dans onSaveInstanceState(Bundle), donc ne présumez pas saveInstanceState sera également non nul dans un Fragment quand il est recréé, comme c'est dans le cas d'un FragmentActivity.

+0

oui. ça m'a aidé. Merci. Eh bien, maintenant je vais lire attentivement la documentation – nail

+0

Dans mon cas, j'affichais un GridView d'images dans mon fragment, mais j'ai remarqué après le changement d'orientation défiler la grille a montré ce qui semblait être des images fantômes derrière la grille. LogCat a montré onCreateView étant appelé plusieurs fois - après avoir fait une vérification nulle pour saveInstanceState dans mon activité, le problème est parti et onCreateView est seulement appelé une fois comme prévu - merci Alex – MarkAArnold

Questions connexes