E 'questo il modo giusto di stack di clean-up indietro Frammento quando si lascia una pila di nidificazione?

StackOverflow https://stackoverflow.com/questions/5802141

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?

È stato utile?

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, e FragmentManager.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 passa POP_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();
    }
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top