9

Kann ich zuerst ein Fragment zu einer Ansicht hinzufügen, dann "trennen" und dann wieder an eine andere Ansicht anhängen?Android-Fragment - Wechsel von einer Ansicht zur anderen?

In Code, ich möchte an:

fragOne one = new fragOne(); 
getSupportFragmentManager().beginTransaction() 
     .add(R.id.left, one, "tag").commit(); 

getSupportFragmentManager().beginTransaction() 
     .detach(one).commit();  // or .remove(), or .addToBackStack(null).remove() 

getSupportFragmentManager().executePendingTransactions(); 

getSupportFragmentManager().beginTransaction() 
     .add(R.id.right, one).commit(); 

Aber es wirft Fehler:

04-05 13:28:03.492: E/AndroidRuntime(7195): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.trybackstack/com.example.trybackstack.MainActivity}: java.lang.IllegalStateException: Can't change container ID of fragment fragOne{40523130 #0 id=0x7f080000 tag}: was 2131230720 now 2131230721 

Dank für die Hilfe!

+0

Sie stehen vor, diese Ausnahme, weil Sie zwei verschiedene IDs für Fragment Behälter verwenden (dh R.id.right und R.id.left) zum Hinzufügen des „Fragment einer“ .Verwendung einer einzigen ID für Container. –

+1

In der Tat. Aber ich möchte dieses Fragment von links nach rechts bewegen. – midnite

+0

In diesem Fall müssen Sie die vorherige Transaktion zuerst festschreiben und dann eine neue Transaktion erneut starten, um das gleiche Fragment zu einer anderen Ansicht hinzuzufügen. –

Antwort

2

Überprüfen Sie die Lösung, Sie müssen die neue Instanz desselben Fragments erstellen und sie mit dem Status des alten Fragments instanziieren, wenn Sie den Status des alten Fragments speichern möchten.

+1

Danke für Ihre Antwort @Karan_Rana! Deine Methode funktioniert. Aber es ist tatsächlich das Fragment duplizieren, aber nicht wirklich _bewegend_ es. Ich habe auch ein paar Leute diesbezüglich gefunden. Ich bin nicht sicher. Aber es scheint für ein Fragment, sobald es hinzugefügt wird, wir können es nicht "neu hinzufügen". Duplizieren scheint die beste Methode zu sein, die ich bisher gefunden habe. Aber es könnte zu einem potentiellen Problem führen: Referenzen davon funktionieren möglicherweise nicht mehr. – midnite

+0

Willkommen @midnite –

8

Ich denke, Sie würden dies jetzt herausgefunden haben, aber ich sehe keine befriedigende Antwort. Also poste ich dies für andere, die sich in Zukunft darauf beziehen können.

Wenn Sie ein Fragment von einer Ansicht zur anderen bewegen Sie wie folgt vor:

android.app.FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction(); 
fragmentTransaction.remove(fragment1); 
fragmentTransaction.commit(); 
fragmentManager.executePendingTransactions(); 
fragmentTransaction = fragmentManager.beginTransaction(); 
fragmentTransaction.add(R.id.containerToMoveTo, fragment1); 
fragmentTransaction.commit(); 

Auf diese Weise müssen Sie nicht das Fragment duplizieren.

+1

Es funktioniert nicht ... Fehler: java.lang.RuntimeException: Aktivität kann nicht gestartet werden ComponentInfo: java.lang.IllegalStateException: Container-ID des Fragments SubMenuFragment {419b9c60 # 1 id = 0x7f050036 nicht geändert werden kann }: war 2131034166 jetzt 2131034167 – Accollativo

+1

Eigentlich funktioniert das. Getestet auf Nexus7/2012/4.4 und Galaxy SII/4.1.2. Was mache ich falsch? =) – mjollneer

+1

Sieht so aus, als ob das nur funktioniert, wenn du einen leeren Backstack hast. Hier ist verbesserter Code: http://StackOverflow.com/a/21328919/1855764 –

0

Ich habe auch auf dieses Problem gestoßen. Manchmal funktioniert das Verschieben von Fragmenten, manchmal müssen Sie eine neue Instanz erstellen. Es scheint, dass das Verschieben von Fragmenten nicht funktioniert, wenn sich das Fragment weiterhin im Status "isRemoving" befindet. Das Entfernen scheint auch verhindert zu werden, indem man ein Fragment im Backstack hat.

9

nach dem versuchen alle Antworten von ähnlichen Fragen, sieht aus wie ich einen Weg gefunden habe, den Trick zu tun.

Erste Ausgabe - Sie wirklich müssen begehen und entfernen Transaktion ausführen, bevor Sie versuchen Fragment in einem anderen Behälter hinzuzufügen. Danke dafür geht an nave's answer

Aber das funktioniert nicht jedes Mal. Das zweite Problem ist ein Backstack. Es blockiert die Transaktion irgendwie.

So ist der vollständige Code, die für mich funktioniert wie folgt aussieht:

manager.popBackStackImmediate(null, manager.POP_BACK_STACK_INCLUSIVE); 
manager.beginTransaction().remove(detailFragment).commit(); 
manager.executePendingTransactions(); 
manager.beginTransaction() 
    .replace(R.id.content, masterFragment, masterTag) 
    .add(R.id.detail, detailFragment, activeTag) 
    .commit();    
+2

Dies führt dazu, dass die Ansicht zerstört und neu erstellt wird, nicht erhalten –

+0

In einigen Fällen wird dies nicht funktionieren. Ich habe bessere Ergebnisse mit der Sequenz in der ursprünglichen Antwort von nave: Fragmente entfernen, backstack und dann Fragmente hinzufügen. – Theo

0

zum Yan. Yurkin's answer Hinzufügen. Stellen Sie sicher, dass keine Transitionen auf die Transaktion angewendet werden, da diese das Trennen des Fragments verzögern.

11

Ich hatte das gleiche Problem, aber ich fand, dass das, was ich wirklich benötigte, war, die Ansicht des Fragments und nicht das Fragment selbst zu reparieren und so jede FragmentManager-Transaktion zu vermeiden.

View vv = fragment.getView(); 
ViewGroup parent = (ViewGroup)vv.getParent(); 
parent.removeView(vv); 
newparent.addView(vv, layoutParams); 
+0

Dies ist die beste Lösung, da die Ansichtshierarchie nicht zerstört und neu erstellt wird. –

+1

Ja, ich stimme dem völlig zu, da der Container in den meisten Szenarien ein einfaches FrameLayout ist und dieser Ansatz das Spielen mit den Fragment- und Fragment-Lebenszyklen vermeidet. –