2011-12-08 10 views
9

Sto utilizzando il pacchetto di compatibilità v4 nel mio progetto e sto riscontrando un problema nel mantenere uno Fragment in giro dopo che è stato rimosso dalla vista. Ho il mio Activity che visualizza 2 frammenti ... una cornice di menu sulla sinistra, riquadro del contenuto sulla destra. La cornice del menu ha 3 diversi menu (Frammenti) che possono essere visualizzati.Come si ripristina un frammento visualizzato in precedenza?

Questo è come mi sto sostituendo il frammento di menu:

public void showMenuFragment(Fragment fragment, String tag) { 

     showFragment(R.id.menu_frame, fragment, tag, false); 
     setLastMenuPushed(tag); 
    } 

protected void showFragment(int resId, Fragment fragment, String tag, boolean addToBackStack) { 

     FragmentManager fragmentManager = getSupportFragmentManager(); 
     FragmentTransaction transaction = fragmentManager.beginTransaction(); 

     if (fragmentManager.findFragmentByTag(tag) != null && fragment.isAdded()) { 
      transaction.remove(fragment); 
     } 

     transaction.replace(resId, fragment, tag).setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN).setBreadCrumbShortTitle(tag); 

     if (addToBackStack) { 
      transaction.addToBackStack(tag); 
     } 

     transaction.commit(); 
    } 

Il menu Fragment s richiedono dati da caricare prima di poter essere visualizzata, così mi mostrano un filatore di carico. Una volta caricato per la prima volta, non voglio caricarlo mai una seconda volta a meno che lo Activity non sia finito.

Quando chiamo showMenuFragment(...) provo a passare in un Fragment utilizzando FragmentManager.findFragmentByTag(String tag) ma è sempre null, quindi devo fare un nuovo Fragment ogni volta che voglio mostrare un menu diverso.

La mia domanda è, come posso mantenere questi Fragment s in giro dopo che sono stati sostituiti da altri menu? Voglio evitare di mantenere i riferimenti manuali allo Fragment s perché quando il dispositivo viene ruotato, l'istanza della mia classe Activity viene distrutta e vorrei perdere quei riferimenti.

MODIFICA: per semplificare i termini, desidero che lo FragmentManager tenga traccia dei precedenti Fragment s senza doverli aggiungere allo stack posteriore. Non voglio premere il pulsante Indietro e vedere il menu precedente mostrato.

risposta

13

Appena capito. Invece di rimuovere Frammenti quando ne aggiungo di nuovi, li nascondo e li mostro quando voglio visualizzarli di nuovo. Ecco i miei metodi modificati:

public void showMenuFragment(Fragment fragment, String tag, boolean addToBackStack) { 

     showFragment(R.id.menu_frame, fragment, tag, getLastMenuPushed(), addToBackStack); 
     setLastMenuPushed(tag); 
} 

protected void showFragment(int resId, Fragment fragment, String tag, String lastTag, boolean addToBackStack) { 

     FragmentManager fragmentManager = getSupportFragmentManager(); 
     FragmentTransaction transaction = fragmentManager.beginTransaction(); 

     if (lastTag != null) { 
      Fragment lastFragment = fragmentManager.findFragmentByTag(lastTag); 
      if (lastFragment != null) { 
       transaction.hide(lastFragment); 
      } 
     } 

     if (fragment.isAdded()) { 
      transaction.show(fragment); 
     } 
     else { 
      transaction.add(resId, fragment, tag).setBreadCrumbShortTitle(tag); 
     } 

     if (addToBackStack) { 
      transaction.addToBackStack(tag); 
     } 

     transaction.commit(); 
} 
+3

Guardando indietro su questo, credo che la soluzione migliore era quella di "staccare" il frammento dal Activity e mantenere un riferimento difficile nella classe. –

+0

Quale sarebbe il vantaggio di detach vs hide? Distruggere la vista fa davvero la differenza? Avete qualche buon modo per ripristinarlo senza ricaricare l'intero frammento? – ben

+0

@ben Detach rimuove la gerarchia della vista dallo schermo, che è un approccio più rispettoso dell'ambiente. La maggior parte delle Views fa un buon lavoro nel salvare il loro stato di istanza quando viene rimosso da un Fragment, quindi non vedrei un grosso problema quando riattaccerò. –

0

Non sono sicuro che sia possibile. FragmentManager si prende SOLO su Fragments sul suo BackStack. Tuttavia, è possibile aggirare il problema del pulsante indietro se si consente allo strumento di implementare e lasciare che il comportamento personalizzato si verifichi. Potresti delegarli al tuo Fragments, o semplicemente mostrare un altro Fragment a seconda della tua App-logic

Problemi correlati