2012-06-22 9 views
14

Ich bin ein One-Aktivität-multiple Fragmente-Anwendung erstellen. Ich füge nach jeder Transaktion dem Backstack hinzu. Nach ein paar Verstecken und Zeigen von Fragmenten und dann Drehen des Telefons, wurden alle Fragmente, die auf dem Container hinzugefügt wurden, wiederhergestellt und jedes Fragment ist übereinander.versteckte Backstack-Fragmente bei Konfigurationsänderung erneut angezeigt

Was kann das Problem sein? Warum zeigt meine Aktivität die Fragmente, die ich zuvor versteckt habe?

Ich denke daran, alle zuvor versteckten, jetzt gezeigten Fragmente zu verstecken, aber gibt es eine "anmutige" Art, dies zu tun?

+0

Just zu beachten, sind versteckte Fragmente bereits in dem Behälter so unsichtbar gehalten. Eine Änderung der Konfiguration könnte sie möglicherweise wieder zeigen, da sie bereits dort sind. – zgulser

Antwort

0

Sie könnten versuchen, die replace() Funktion zu verwenden, anstatt zu verbergen und anzuzeigen. Ich hatte das gleiche Problem, als ich anfing, Fragments zu verwenden, und die Ersatzfunktion zu verwenden, half wirklich, die Fragments besser zu handhaben. Hier ist ein kurzes Beispiel:

fragmentManager.replace(R.id.fragmentContainer, desiredFragment, DESIRED_FRAGMENT_TAG)         
       .addToBackStack(null) 
       .commit(); 
9

Verwenden setRetainInstance(true) auf jedes Fragment und das Problem verschwindet.
Warnung: Wenn Sie dies auf "true" setzen, ändert sich der Lebenszyklus des Fragments.
Während setRetainInstance(true) das Problem behebt, kann es Fälle geben, in denen Sie es nicht verwenden möchten. das beheben, Einrichten eines booleschen Attribut für das Fragment und Wiederherstellen der Sichtbarkeit:

private boolean mVisible = true; 
@Override 
public void onCreate(Bundle _savedInstanceState) { 
    super.onCreate(_savedInstanceState); 
    if (_savedInstanceState!=null) { 
     mVisible = _savedInstanceState.getBoolean("mVisible"); 
    } 
    if (!mVisible) { 
     getFragmentManager().beginTransaction().hide(this).commit(); 
    } 
    // Hey! no setRetainInstance(true) used here. 
} 
@Override 
public void onHiddenChanged(boolean _hidden) { 
    super.onHiddenChanged(_hidden); 
    mVisible = !_hidden; 
} 
@Override 
public void onSaveInstanceState(Bundle _outState) { 
    super.onSaveInstanceState(_outState); 
    if (_outState!=null) { 
     _outState.putBoolean("mVisible", mVisible); 
    } 
} 

Sobald die Konfigurationsänderungen (zB Bildschirmausrichtung), wird die Instanz zerstört, aber das Bündel wird auf die gespeicherten und injiziert werden, neue Fragment-Instanz

2

Ich hatte das gleiche Problem. Sie sollten den Quellcode in der Funktion onCreateView() Ihrer Aktivität überprüfen.

public class MainActivity extends Activity { 
@Override 
protected void onCreate(Bundle savedInstanceState) { 
    setContentView(R.layout.activity_main); 

    if(savedInstanceState == null){//for the first time 

     FragmentManager fragmentManager = getFragmentManager(); 
     FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction(); 

     FragmentExample fragment = new FragmentExample(); 
     fragmentTransaction.add(R.id.layout_main, fragment); 
     fragmentTransaction.commit(); 

    }else{//savedInstanceState != null 
     //for configuration change or Activity UI is destroyed by OS to get memory 
     //no need to add Fragment to container view R.id.layout_main again 
     //because FragmentManager supported add the existed Fragment to R.id.layout_main if R.id.layout_main is existed. 
     //here is one different between Fragment and View 

    } 
} 

activity_main.xml:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
xmlns:tools="http://schemas.android.com/tools" 
android:layout_width="match_parent" 
android:layout_height="match_parent" 
android:id="@+id/layout_main">