2012-12-04 18 views
15

Il back stack supporta l'interazione con frammenti nidificati in Android?Frammenti nidificati e back stack

Se sì, cosa sto sbagliando? Nella mia implementazione, il pulsante Indietro ignora completamente il fatto che ho aggiunto questa transazione allo stack posteriore. Spero che non sia a causa di un problema con frammenti annidati e solo a fare qualcosa in modo errato.

Il seguente codice si trova all'interno di uno dei miei frammenti e viene utilizzato per scambiare un nuovo frammento con qualunque nidificato frammento è attualmente in mostra:

 MyFragment fragment = new MyFragment(); 
    FragmentTransaction ft = getChildFragmentManager().beginTransaction(); 
    ft.setCustomAnimations(R.animator.slide_in_from_right, R.animator.slide_out_left, R.animator.slide_in_from_left, R.animator.slide_out_right); 
    ft.addToBackStack(null); 
    ft.replace(R.id.myFragmentHolder, fragment); 
    ft.commit(); 
+0

Chiunque vedendo questo OP può assumere uno sguardo a un altro, http://stackoverflow.com/questions/13418436/android-4-2-back-stack-behaviour-with-nested-fragments, che spiega meglio. – lcn

risposta

28

Ho lo stesso problema, vorrei frammenti nido, e per mantenere uno stack posteriore per ogni frammento annidato.

Ma ... sembra che questo caso non sia gestito dalla libreria di supporto v4. Nel codice FragmentActivity nella libreria, posso trovare:

public void onBackPressed() { 
    if (!mFragments.popBackStackImmediate()) { 
     finish(); 
    } 
} 

I mFragments rappresenta la FragmentManager dell'attività, ma non sembra questo manager "propaga" pop per bambini manager. Una soluzione potrebbe essere quella di chiamare manualmente il popBackStackImmediate() sul gestore bambino, come questo nell'attività ereditato da FragmentActivity:

private Fragment myFragmentContainer; 

    @Override 
    public void onBackPressed() { 
      if (!myFragmentContainer.getChildFragmentManager().popBackStackImmediate()) { 
       finish(); //or call the popBackStack on the container if necessary 
      } 
    } 

Ci potrebbe essere un modo migliore, e un modo più automatico, ma per le mie esigenze va tutto bene.

+0

Hmm Darò uno scatto dopo e accetto se funziona. – MikeS

+0

Questo non sembra funzionare. In primo luogo, Fragments non ha un metodo popBackStackImmediate() (solo FragmentManagers). Ho provato a sostituire 'this.getFragmentManager(). PopBackStackImmediate()', ma fondamentalmente non ho visto nulla di diverso da quello che stava già accadendo. – MikeS

+1

Dopo aver lavorato con quello che mi hai dato, ho trovato la soluzione! Modificherò la tua risposta per contenere la soluzione e la contrassegnerò come accettata poichè mi metti la maggior parte della strada verso la risposta giusta ... – MikeS

-2
@Override 
public void onBackPressed() { 
    FragmentManager fm = getSupportFragmentManager(); 
    if (fm.getBackStackEntryCount() > 0) { 
     fm.popBackStack(); 
     return; 
    } 
    finish(); 
} 
+0

Si prega di aggiungere alcune spiegazioni sulla risposta. – DontVoteMeDown

4

Nel mio progetto attuale abbiamo più "livelli nidificati" così mi è venuta in mente seguente soluzione alternativa al pop automaticamente backstack solo per i top manager frammento livello:

@Override 
public void onBackPressed() { 
    SparseArray<FragmentManager> managers = new SparseArray<>(); 
    traverseManagers(getSupportFragmentManager(), managers, 0); 
    if (managers.size() > 0) { 
     managers.valueAt(managers.size() - 1).popBackStackImmediate(); 
    } else { 
     super.onBackPressed(); 
    } 
} 

private void traverseManagers(FragmentManager manager, SparseArray<FragmentManager> managers, int intent) { 
    if (manager.getBackStackEntryCount() > 0) { 
     managers.put(intent, manager); 
    } 
    if (manager.getFragments() == null) { 
     return; 
    } 
    for (Fragment fragment : manager.getFragments()) { 
     if (fragment != null) traverseManagers(fragment.getChildFragmentManager(), managers, intent + 1); 
    } 
} 
Problemi correlati