2012-02-09 17 views
33

enter image description hereAndroid Rimuovere Frammento e vista dalla BackStack

Mi rendo conto che questa domanda è stato chiesto prima però le risposte precedenti mi hanno ottenuto finora. Lo scenario è il seguente: abbiamo un frammento dashboard (A), che porta un utente a una schermata di accesso (B). In caso di accesso riuscito vanno a un listview (c). Nel backpress vorrei tornare ad A, poiché l'utente non avrà più bisogno di vedere la schermata di login. Inoltre, in caso di accesso riuscito, memorizziamo i dettagli nelle preferenze condivise e automatizziamo il login in B la prossima volta, che funziona come pianificato.

Ho il seguente metodo di FragmentHelper:

public static void goToNextFragement(Fragment fragment, int container, boolean addToBackStack, Fragment ctx) 
    { 
     // Create new fragment and transaction 
     FragmentTransaction transaction = ctx.getSupportFragmentManager().beginTransaction(); 
     transaction.setCustomAnimations(R.anim.slide_in_left, R.anim.slide_out_right); 
     // Replace whatever is in the fragment_container view with this fragment, 
     // and add the transaction to the back stack 
     transaction.replace(container, fragment); 

     if(addToBackStack) 
      transaction.addToBackStack(null); 

     // Commit the transaction 
     transaction.commit(); 
    } 

Nella transazione da B a C ho impostato il booleano addToBackStack come falsa in modo che il transaction.addToBackStack(null); non viene chiamato. Questo funziona ancora bene ma dopo è dove inizia il mio problema.

Quando l'utente preme nuovamente C e ritorna A I può ancora vedere la vista gonfiata C sotto la vista di A.

Tutto l'aiuto sarebbe apprezzato. Spero che il mio diagramma aiuti a mantenere questo semplice.

risposta

1

paio di modi per gestire questo:

  1. ho avuto un flusso simile nella mia app e il modo in cui ho risolto era sostituendo il frammento di accesso con un AlertDialog che è licenziato dalla principale attività. Quindi nel tuo caso, il frammento A appare sullo schermo e se l'attività principale pensa di dover mostrare la finestra di accesso, mostra AlertDialog. Questo ha funzionato per me.

  2. Quando il frammento A è abilitato, può controllare se il frammento C è in giro chiedendo al FragmentManager. Se esiste, rimuovilo.

+0

The AlertDialogue era la strada da percorrere. Grazie per aver condiviso la tua esperienza. –

+16

Questo è piuttosto una soluzione alternativa non una soluzione reale, vero? – Brian

+2

risposta non accettabile –

0

Non dire all'FM che si desidera che la transizione da B a C sia aggiunta al backStack significa che quando si preme indietro, la FM non ha registrazioni di aggiunta di C, quindi non la rimuove.

+0

OK Ho pensato che forse il caso, tuttavia (a rischio di sembrare ingrato per l'aiuto, che io non sono) questo fornisce un'analisi del problema e non la soluzione. Hai qualche idea su come aggirare/risolvere questo problema? –

+0

In cima alla mia testa, è possibile rimuovere manualmente quel frammento, ma probabilmente non è l'opzione migliore. Oltre a questo, dovrai fare i tuoi compiti. –

21

Ho risolto questo .. all'interno di una linea ...

getFragmentManager().popBackStack(); 

o

getSupportFragmentManager().popBackStack() 

questo funziona quando si aggiungono frammenti e mantenere backstack (non sostituire).

+0

risposta reale, grazie –

+1

Quando si esegue il backstack prima di passare dal sistema 2 al 3 cercando di mostrare il frammento 1. Ogni volta che si inserisce il numero di frammento N, si tenta di mostrare il numero di frammento (N-1). E se imposti di andare al frammento 3 otterrai NPE durante onCreateView di 1 frammento ... – Yazon2006

6

f1 -> f2

Fragment2 f2 = new Fragment2(); 
this.getActivity().getSupportFragmentManager().beginTransaction().replace(R.id.main_content,f2).addToBackStack(null).commit(); 

nulla di straordinario qui. Rispetto al frammento f2 questo codice porta al frammento f3.

f2 -> f3

Fragment3 f3 = new Fragment3(); 
getActivity().getSupportFragmentManager().popBackStack(); 
getActivity().getSupportFragmentManager().beginTransaction().replace(R.id.main_content, f3).addToBackStack(null).commit(); 

Non sono sicuro leggendo documenti, se questo dovrebbe funzionare, questo metodo di transazione Poping si dice che sia asincrona, e forse un modo migliore sarebbe quello di chiamare popBackStackImmediate() . Ma per quanto posso dire sui miei dispositivi funziona perfettamente.

Il suddetto alternativa sarebbe:

final FragmentActivity activity = getActivity(); 
activity.getSupportFragmentManager().popBackStackImmediate(); 
activity.getSupportFragmentManager().beginTransaction().replace(R.id.main_content, f3).addToBackStack(null).commit(); 

Qui ci saranno effettivamente essere breve tornare a f1 beofre passare a f3, quindi un leggero problema tecnico lì.

questo è in realtà tutto quello che dovete fare e questo answer può anche aiutare un sacco ..

+0

la tua soluzione è molto molto perfetta per il mio problema, risparmierai il mio tempo su Nepster. –

0

Passo 1: Quando sei in Frammento A e vuole aprire frammento B

getFragmentManager().beginTransaction() 
.replace(android.R.id.content, new FragmentB(), FragmentB.class.getName() 
.addToBackStack(null) 
.commit(); 

Passo 2: Quando sei in frammento B, e si desidera aprire Frammento C

getFragmentManager().beginTransaction() 
.replace(android.R.id.content, new FragmentC(), FragmentC.class.getName() 
.disallowAddToBackStack() // << this to make Fragment B, not included in the backstack 
.commit(); 

Passo 3: Quando you'in nel frammento C, ed il dispositivo premendo di nuovo il pulsante o getFragmentManager().popBackStack(); voi verrà aperto il frammento A.

PS: In Attività utilizzare questo getSupportFragmentManager(). Se sei in Frammento usa questo getFragmentManager()

0

Ciao, volevo solo condividere la soluzione elegante che ho trovato.

public static void performNoBackStackTransaction(FragmentManager fragmentManager, String tag, Fragment fragment) { 
final int newBackStackLength = fragmentManager.getBackStackEntryCount() +1; 

fragmentManager.beginTransaction() 
    .replace(R.id.content, fragment, tag) 
    .addToBackStack(tag) 
    .commit(); 

fragmentManager.addOnBackStackChangedListener(new FragmentManager.OnBackStackChangedListener() { 
    @Override 
    public void onBackStackChanged() { 
    int nowCount = fragmentManager.getBackStackEntryCount(); 
    if (newBackStackLength != nowCount) { 
     // we don't really care if going back or forward. we already performed the logic here. 
     fragmentManager.removeOnBackStackChangedListener(this); 

     if (newBackStackLength > nowCount) { // user pressed back 
     fragmentManager.popBackStackImmediate(); 
     } 
    } 
    } 
}); 
} 

Source with explained logic.

Problemi correlati