E 'questo il modo giusto di stack di clean-up indietro Frammento quando si lascia una pila di nidificazione?
-
22-10-2019 - |
Domanda
Sto utilizzando la libreria di compatibilità Android per implementare frammenti e hanno esteso il campione di layout in modo che un frammento contiene un pulsante che spara un altro frammento.
Nel riquadro di selezione a sinistra ho 5 elementi selezionabili -. A B C D E
Ogni carichi fino un frammento (via FragmentTransaction:replace
) nel riquadro dei dettagli - a b c d e
e
frammento Ora ho esteso per contenere un pulsante che carichi un altro frammento e1
anche nel riquadro dei dettagli. Ho fatto questo sul metodo onClick di e
frammento come segue:
FragmentTransaction ft = getActivity().getSupportFragmentManager().beginTransaction();
ft.replace(R.id.details_frag, newFrag);
ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
ft.addToBackStack(null);
ft.commit();
Se faccio le seguenti selezioni:
E - e - e1 - D - E
Poi e
frammento è nel riquadro dei dettagli. Questo va bene e quello che voglio. Tuttavia, se ho colpito il tasto back
a questo punto non si fa nulla. Devo cliccare due volte perché e1
è ancora in pila. Inoltre dopo aver fatto clic in giro ho ottenuto un'eccezione di puntatore nullo in onCreateView:
Per 'risolvere' il problema ho aggiunto il seguente ogni volta che viene selezionato A B C D E
:
FragmentManager fm = getActivity().getSupportFragmentManager();
for(int i = 0; i < fm.getBackStackEntryCount(); ++i) {
fm.popBackStack();
}
Basta chiedersi se questa è la soluzione corretta o se devo fare qualcosa di diverso?
Soluzione
Beh, ci sono alcuni modi per andare su questo in base al comportamento previsto, ma questo link dovrebbe darvi tutte le migliori soluzioni e non a caso è da Dianne Hackborn
http://groups.google.com/group/android-developers/browse_thread/thread / d2a5c203dad6ec42
In sostanza si hanno le seguenti opzioni
- Utilizzare un nome per il tuo stato pila avanti iniziale e l'uso
FragmentManager.popBackStack(String name, FragmentManager.POP_BACK_STACK_INCLUSIVE)
. - Usa
FragmentManager.getBackStackEntryCount()
/getBackStackEntryAt().getId()
per recuperare l'ID del primo ingresso nello stack schiena, eFragmentManager.popBackStack(int id, FragmentManager.POP_BACK_STACK_INCLUSIVE)
. -
FragmentManager.popBackStack(null, FragmentManager.POP_BACK_STACK_INCLUSIVE)
si suppone pop l'intero stack indietro ... Credo che la documentazione per che è solo sbagliato. (In realtà credo che semplicemente non copre il caso in cui si passaPOP_BACK_STACK_INCLUSIVE
),
Altri suggerimenti
L'altra soluzione pulita, se non si vuole far apparire tutte le voci dello stack ...
getSupportFragmentManager().popBackStack(null, FragmentManager.POP_BACK_STACK_INCLUSIVE);
getSupportFragmentManager().beginTransaction().replace(R.id.home_activity_container, fragmentInstance).addToBackStack(null).commit();
Questo pulire lo stack e poi caricare un nuovo frammento, quindi in un qualsiasi punto dovrai solo singolo frammento nello stack
Grazie a Joachim risposta, io uso il codice per cancellare tutte le entrate dello stack di nuovo alla fine.
// In your FragmentActivity use getSupprotFragmentManager() to get the FragmentManager.
// Clear all back stack.
int backStackCount = getSupportFragmentManager().getBackStackEntryCount();
for (int i = 0; i < backStackCount; i++) {
// Get the back stack fragment id.
int backStackId = getSupportFragmentManager().getBackStackEntryAt(i).getId();
fm.popBackStack(backStackId, FragmentManager.POP_BACK_STACK_INCLUSIVE);
} /* end of for */
Ho studiato molto per la pulizia Backstack, e finalmente vedere Transaction BackStack e la sua gestione . Ecco la soluzione che ha funzionato meglio per me.
// CLEAR BACK STACK.
private void clearBackStack() {
final FragmentManager fragmentManager = getSupportFragmentManager();
while (fragmentManager.getBackStackEntryCount() != 0) {
fragmentManager.popBackStackImmediate();
}
}
Il metodo di cui sopra loop su tutte le transazioni nel backstack e li rimuove immediatamente una alla volta.
Nota: sopra il codice a volte non funziona e faccia i ANR a causa di questo codice, quindi per favore non provare questo.
Aggiorna di seguito il metodo rimuovere tutti fregment di quel "nome" da backstack.
FragmentManager fragmentManager = getSupportFragmentManager();
fragmentManager.popBackStack("name",FragmentManager.POP_BACK_STACK_INCLUSIVE);
- nome se non nullo, questo è il nome di uno stato precedente indietro cercare; se trovato, tutti gli stati fino a quello stato saranno spuntato. Il
- bandiera POP_BACK_STACK_INCLUSIVE può essere utilizzato per controllare se la stessa condizione di nome è spuntato. Se nulla, solo lo stato superiore è spuntato.
Io sto usando un codice simile a quelli che utilizzano il ciclo while ma chiamare il numero di registrazioni in ogni ciclo ... quindi suppongo che sia un po 'più lento
FragmentManager manager = getFragmentManager();
while (manager.getBackStackEntryCount() > 0){
manager.popBackStackImmediate();
}
// pop back stack all the way
final FragmentManager fm = getSherlockActivity().getSupportFragmentManager();
int entryCount = fm.getBackStackEntryCount();
while (entryCount-- > 0) {
fm.popBackStack();
}