2012-11-28 21 views
7

Ecco cosa vorrei fare la mia applicazione su un tablet. Fragment (0) ha alcuni menu che visualizzerebbe frammenti (1) ... (n) come questo:sposta il frammento Android in un contenitore diverso Impossibile modificare l'ID contenitore del frammento

----------------- 
| | | | | 
| | | | | 
|(0)| X | X | X | 
| | | | | 
| | | | | 
----------------- 
becomes 
----------------- 
| | | | | 
| | | | | 
|(0)|(1)| X | X | 
| | | | | 
| | | | | 
----------------- 
and then 
----------------- 
| | | | | 
| | | | | 
|(0)|(2)|(1)| X | 
| | | | | 
| | | | | 
----------------- 
etc... 

Fragment0 non si muove, gli altri vengono spostati a destra. Frammenti che vanno dal bordo a destra saranno distrutti.

Così ho configurato il mio layout XML con un LinearLayout orizzontale e contenente 4 FrameLayout con le dovute ID (fragment0 ... fragment3)

posso un'istanza e visualizzazione fragment0 e poi fragment1, ma io non sono in grado di spostare a destra dopo, ottengo:

ERROR/AndroidRuntime(343): FATAL EXCEPTION: main 
java.lang.IllegalStateException: Can't change container ID of fragment ... 

le sole questioni connesse che ho trovato sono this one e that one, ha provato tutte le diverse soluzioni offerte senza fortuna.

Provato FragmentTransaction.remove() seguito da .add(), provato .replace(), li provato in diversi ordini e di impegnarsi a metà (anche cercando di commettere due volte come qualcuno ha suggerito), ha cercato di chiamare addToBackStack() ... ancora senza fortuna.

Domanda è se è possibile spostare i frammenti come questo con FragmentTransaction. Se sì, cosa sto sbagliando (e bonus, è possibile animarlo?). Se no, quale sarebbe il modo corretto di implementarlo?

Nota che non voglio ripetere l'istanza dei frammenti ogni volta (ognuno fa alcune query sul web che possono richiedere del tempo). È possibile estrarre tutti i dati di nuovo all'attività per ricrearne uno, ma preferirei non farlo se possibile ...

risposta

3

Non so se questo è proprio quello che vuoi ma ho fatto un piccolo campione per quanto riguarda il tuo problema. Fondamentalmente farai il cambio giusto usando il file di layout, avendo un contenitore wrapper per ciascuno di quei frammenti mobili. L'esempio di codice è un po 'troppo grande per una risposta, quindi l'ho inserito in a gist that you can find here. In quel campione, premere ciascuno degli elementi di ListFragment (Frammento 1 -> Frammento 2 -> frammento 3) per vedere il comportamento.

+0

Non fa quello che sto cercando, ma sto cercando di cambiare il tuo codice per farlo ... Lo posterò se riesco a ... – Matthieu

+0

È stato in grado di fare ciò di cui avevo bisogno .. Non riuscivo a capire come spingere le mie modifiche alla sostanza che hai creato, quindi l'ho messo lì: https://gist.github.com/4166640 – Matthieu

+0

Scusami. È un refuso, che dovrebbe essere 'LinearLayout' invece di' RelativeLayout' in 'frag_fragaccordion.xml'? – midnite

20

Si il contenitore del frammento può essere modificato utilizzando la funzione remove().

Il problema è commit(). È una chiamata asincrona e pianificherà che si trovi sul thread principale. Quindi per forzare lo FragmentManager a farlo immediatamente prima di aggiungerlo all'altro contenitore.

Per questo dovremo utilizzare la funzione executePendingTransactions(). Dopo aver chiamato questo, prova ad aggiungere il frammento al nuovo contenitore.

Documenti: executePendingTransactions()

codice di esempio:

FragmentManager fManager = getSupportFragmentManager(); 
FragGroups fragGroups = (FragGroups) fManager.findFragmentByTag("groups"); 
if (fragGroups != null) { 
    fManager.beginTransaction().remove(fragGroups).commit(); 
    fManager.executePendingTransactions(); 
} else { 
    fragGroups = new FragGroups(); 
} 
if (mTwoPane) { 
    fManager.beginTransaction().replace(R.id.fragment_container_groups, fragGroups, "groups").commit(); 
} else { 
    fManager.beginTransaction().replace(R.id.fragment_container, fragGroups, "groups").commit(); 
} 

godere.Feed-back vengono accolti

Modifica

Vorrei una aggiungere un punto qui. Come ho avuto lo stesso problema, mi sono imbattuto in questo thread e ho applicato le modifiche suggerite. Il problema persisteva ancora. Poi ho esaminato l'ultimo commento in questo thread che ha risolto il mio problema: rimuovere il metodo addToBackStack() durante il commit di una transazione o se lo si utilizza intenzionalmente, rimuovere il frammento dal back stack prima di aggiungerlo a un altro contenitore. Spero che possa aiutare il futuro lettore.

+1

Ottima risposta! Potrebbe non essere esattamente quello che cercava la domanda originale, ma l'ho trovato estremamente utile. –

+2

Pavan ..... Non ti conosco nemmeno ... non mi conosci nemmeno ... ma ho un amore serio per te, amico mio. – dell116

+0

@TomR Sono contento che l'abbia trovato utile :) –

Problemi correlati