replace()
fa 2 cose:
- Rimuovere frammento attualmente aggiunto (A) dal contenitore (C) hai indicato
- Aggiungi nuovo frammento (B) per lo stesso contenitore
Queste 2 operazioni sono ciò che viene salvato come record/transazione Backstack. Si noti che il frammento A rimane nello stato created
e la sua vista viene distrutta.
Ora popBackStack()
inverte l'ultima transazione che hai aggiunto a BackStack.
In questo caso, che sarebbe a 2 passi:
- Rimuovere B da C
- Aggiungi A a C
Dopo questo, frammento B diventa detached
, e se non avete tenuto riferimenti ad esso, sarà garbage collection.
Per rispondere alla prima parte della domanda, non c'è la chiamata onCreate()
, perché FragmentB è rimasto nello stato created
. E rispondere alla seconda parte della domanda è un po 'più lungo.
Innanzitutto, è importante capire che in realtà non si aggiunge Fragments
a Backstack, si aggiunge FragmentTransactions
. Quindi, quando pensi di "sostituire con Frammento B, aggiungendo Frammento A allo stack posteriore", aggiungi effettivamente l'intera operazione a backstack - ovvero sostitutiva di A con B. Questa sostituzione consiste di 2 azioni - rimuovi A e aggiungi B.
Quindi, il passaggio successivo è il popping della transazione che contiene questa sostituzione. Quindi non stai scoccando FragmentA, stai invertendo "rimuovi A, aggiungi B", che invertito è "rimuovi B, aggiungi A".
E poi passo finale dovrebbe essere più chiaro - non c'è B che FragmentManager è a conoscenza, in modo che quando lo si aggiunge sostituendo A con B al vostro ultimo passo, B ha la necessità di passare attraverso i suoi primi metodi del ciclo di vita - onAttach()
e onCreate()
.
Il seguente codice illustra cosa sta succedendo.
FragmentManager fm = getFragmentManager();
FragmentA fragmentA = new FragmentA();
FragmentB fragmentB = new FragmentB();
// 1. Show A
fm.beginTransaction()
.add(fragmentA, R.id.container)
.commit();
// 2. Replace A with B
// FragmentManager keeps reference to fragmentA;
// it stays attached and created; fragmentB goes
// through lifecycle methods onAttach(), onCreate()
// and so on.
fm.beginTransaction()
.replace(fragmentB, R.id.container)
.addToBackstack(null)
.commit();
// 2'. Alternative to replace() method
fm.beginTransaction()
.remove(fragmentA)
.add(fragmentB, R.id.container)
.addToBackstack(null)
.commit();
// 3. Reverse (2); Result - A is visible
// What happens:
// 1) fragmentB is removed from container, it is detached now;
// FragmentManager doesn't keep reference to it anymore
// 2) Instance of FragmentA is placed back in the container
// Now your Backstack is empty, FragmentManager is aware only
// of FragmentA instance
fm.popBackStack();
// 4. Show B
// Since fragmentB was detached, it goes through its early
// lifecycle methods: onAttach() and onCreate().
fm.beginTransaction()
.replace(fragmentB, R.id.container)
.addToBackstack(null)
.commit();
'getFragmentManager(). PopBackStackImmediate();' ha fatto il trucco. Grazie. –
Dove metterei questo metodo? Nel mio listener di schede? – rasen58
senza vedere il codice, è difficile da dire ... ma dovrebbe andare nella sezione di codice che viene eseguita quando si desidera "chiudere" il frammento corrente e tornare al frammento precedente. – stuckless