5

Ho un Activity con tre frammenti permette loro di A, B e C chiamare. FragmentA viene chiamato nell'attività onCreate().Prevenire lo stesso frammento Da impilabile più di una volta (addToBackStack)

FragmentA fragA = new FragmentA(); 
FragmentTransaction transaction = manager.beginTransaction(); 
transaction.add(R.id.activity2_layout, fragA, "A"); 
transaction.commit(); 

e viene sostituito con frammento B o C quando vengono premuti alcuni pulsanti, e il FragmentTransaction chiamate addToBackStack().

FragmentB fragB = new FragmentB(); //or C 
FragmentTransaction transaction = manager.beginTransaction(); 
transaction.replace(R.id.activity2_layout, fragB, "B"); //or C 
transaction.addToBackStack("B"); //or C 
transaction.commit(); 

Ma consente di dire che io chiamo FragmentB tre volte di fila, come posso evitare che accatastamento su di esso di sé? E allo stesso tempo, voglio che questo sia possibile: B chiamato>C chiamato>B chiamato - ma quando provo a tornare voglio B da aprire solo una volta (C < B) invece di (B < C < B). Quindi sostanzialmente rimuovendo il primo backStack con quello nuovo.

risposta

8

Da How to resume Fragment from BackStack if exists, che potrebbe essere molto simile alla tua richiesta.

C'è un modo per inserire il back stack in base al nome della transazione o all'ID fornito da commit (ad es.utilizzando il nome del frammento classe come Thijs già detto):

String backStateName = fragment.getClass().getName(); 

Aggiungendo a backstack:

FragmentTransaction ft = manager.beginTransaction(); 
ft.replace(R.id.content_frame, fragment); 
ft.addToBackStack(backStateName); 
ft.commit(); 

Quando popping:

getSupportFragmentManager().popBackStackImmediate (backStateName, 0); 

Quindi, prima di sostituire frammento, possiamo controllare esistenza in backstack come:

boolean fragmentPopped = manager.popBackStackImmediate (backStateName, 0); 

if (!fragmentPopped){ //fragment not in back stack, create it. 
    ... 
    ... 
    ft.addToBackStack(backStateName); 
    ft.commit(); 
} 

Si prega di controllare la domanda di cui sopra e la risposta accettata per ulteriori spiegazioni.

+0

Questa è la risposta migliore in quanto risponde a entrambe le domande :) –

1

Ho risolto una delle tue domande, ovvero how can I prevent it from stacking on to it self?, in uno dei miei progetti qualche tempo fa. Questo è stato il codice esatto non ho usato:

public void setContent(@NonNull Fragment fragment, boolean addToBackStack) { 
    Fragment current = getSupportFragmentManager().findFragmentById(R.id.main_content); 
    if (current == null || !current.getClass().equals(fragment.getClass())) { 
     FragmentTransaction transaction = getSupportFragmentManager().beginTransaction(); 
     if (addToBackStack) { 
      transaction.addToBackStack(null).add(R.id.main_content, fragment).commit(); 
     } else { 
      transaction.replace(R.id.main_content, fragment).commit(); 
     } 
    } 
} 

Che questo codice non fa altro che controlli della quale classe attualmente mostrando frammento è e si confronti con il frammento che si desidera sostituirlo con. Se sono uguali, non fa nulla. Questo codice può essere modellato per soddisfare le vostre esigenze in questo modo

Fragment newFragment = new FragmentB(); //OR FragmentC 
Fragment current = getSupportFragmentManager().findFragmentById(R.id.activity2_layout); 
if (!current.getClass().equals(newFragment.getClass())) { 

    //POP BACKSTACK HERE LIKE EXPLAINED BELOW 

    FragmentTransaction transaction = getSupportFragmentManager().beginTransaction(); 
    final String tag = newFragment.getClass().getSimpleName(); 
    transaction.addToBackStack(tag); 
    transaction.add(R.id.activity2_layout, newFragment, tag); 
    transaction.commit(); 
} else { 
    //THROW AN ERROR OR SOMETHING, HANDLE IT BEING THE SAME 
} 

Fare in modo che solo un frammento di un certo tipo è presente in un momento potrebbe probabilmente essere raggiunto schioccare la backstack fino a prima della prima occorrenza dello stesso frammento . Non ho scritto alcun codice per questo, ma non dovrebbe essere troppo difficile implementarlo. Se non riesci a capirlo da solo, fammi sapere e proverò a scriverti un esempio :)

+0

Grazie :) Nessun esempio non sarà necessario :) L'unica cosa che ho bisogno di capire ora è come rimuovere i backStacks che sono già stati fatti, se è possibile anche perché non riesco a trovare alcuna documentazione o esempi su quella. –

+1

Non penso che sia possibile. Per quanto ne so, il 'FragmentManager' ha uno e un solo backstack. Puoi eliminare le voci e aggiungerne un'altra per "sostituire" quella quantità di voci con una nuova voce. Fintanto che lo fai prima di 'commit()', dovresti stare bene :) –

+0

@IvanJavorovic rimuovendo i backStacks vuoi dire cancellare il back stack? –

Problemi correlati