13

Ho difficoltà a capire come gestire correttamente Fragment s in un modello di progettazione elenco-dettaglio tipico.Come gestire lo stato dell'interfaccia utente e lo stack posteriore in un layout a singolo/doppio riquadro

mio layout sta funzionando benissimo ed è strutturato come questo per il paesaggio (doppio pannello):

<?xml version="1.0" encoding="utf-8"?> 
<LinearLayout ... > 
    <FrameLayout android:id="@+id/list" ... /> 
    <FrameLayout android:id="@+id/container" ... /> 
</LinearLayout> 

E così per la vista ritratto (riquadro singolo):

<?xml version="1.0" encoding="utf-8"?> 
<FrameLayout android:id="@+id/container" ... /> 

I avere anche refs.xml in res/values-w600dp/ per assicurarsi che il layout appropriato venga caricato in base alla larghezza dello schermo del dispositivo.

Quando si seleziona una voce di elenco, la vista orizzontale dovrebbe mostrare l'elenco e i dettagli fianco a fianco, mentre la vista verticale dovrebbe mostrare solo i dettagli a schermo intero. Quando non è stato selezionato nulla, la vista orizzontale dovrebbe mostrare la sinistra a sinistra e lo spazio vuoto a destra, mentre la vista verticale dovrebbe mostrare solo l'elenco a schermo intero.

example

Tuttavia, ecco dove sto avendo problemi:

  • si usa un "principale" Activity per il layout dettagli optional lista +, e un altro "dettagli" Activity per la ritratto, layout solo per i dettagli? Questo sembra essere quello che fa l'esempio . Ho ottenuto questo approccio per funzionare in generale, ma come faccio a mantenere lo stato del mio frammento di dettagli quando l'orientamento cambia?

    Si consideri il caso opposto mostrato sopra - in rotazione da verticale a orizzontale, mentre i dettagli sono visibili significa che i dettagli Activity avrebbe bisogno di essere finish() ed in modo che il principale Activity potrebbe visualizzare il layout a due pannelli, ma questo distrugge anche i dettagli frammento e il suo savedInstanceState. Se l'utente ha immesso le informazioni nei campi EditText nel frammento di dettagli, quindi ruota il dispositivo, come posso conservare l'intero stato dell'interfaccia utente del frammento di dettagli quando lo aggiungo al file principale (due riquadri) Activity?

  • È possibile utilizzare solo uno Activity e gestire da solo il Fragment s? Ciò mi consente di mantenere lo stato dell'interfaccia utente dei dettagli quando l'orientamento cambia (perché Android si occupa automaticamente di questo), ma diventa disordinato quando si tratta del back stack.

    Considerate il caso nell'immagine - ruotando da orizzontale a verticale quando i dettagli sono visibili dovrebbe mostrare i dettagli del singolo riquadro, ma come gestisco correttamente il back stack e l'icona di casa ActionBar per mostrare l'elenco single- Pane? Girare di nuovo in orizzontale dovrebbe anche annullare qualsiasi manipolazione dello stack precedente che ho fatto in precedenza, dato che entrambi i frammenti saranno visibili contemporaneamente.

Dopo un po 'di più ricerca, ho trovato due domande simili (Switch from dual pane to single pane on orientation change maintaining fragment stack e Retain Fragment state between Activities), ma la mia situazione è leggermente diversa perché io non sto cercando di retrofit questa funzionalità, ma piano migliore per esso in anticipo. Cosa mi manca? Sicuramente Android può gestire sia lo stack posteriore (come nel caso multiplo Activity) e lo stato dell'interfaccia utente (come nel caso singolo Activity) in una sola volta, giusto?

risposta

6

Ho risolto questo facendo il percorso delle attività multiple. See my answer to "Retain Fragment state between Activities".

Il tasto utilizzava FragmentManager.saveFragmentInstanceState() per salvare lo stato dell'interfaccia utente del frammento e Fragment.setInitialSavedState() per ripristinarlo durante l'istanziazione dello stesso frammento in un'altra attività.

Per i miei scopi, ho scoperto che avevo bisogno di salvare lo stato dell'interfaccia utente in due casi. Ho creato un metodo di supporto public void saveState() all'interno del mio frammento e lo chiamiamo dal metodo onPause() del frammento nonché dalla mia attività "principale" immediatamente prima dell'uso di replace() per collegare una nuova istanza del frammento al layout a doppio riquadro.

Sono ancora interessato a sapere se la manipolazione dello stack posteriore necessaria per questo tipo di scenario singolo/doppio riquadro layout è possibile o se l'unico approccio attività richiederebbe l'override onBackPressed e la simulazione di un pila di nuovo manualmente.

4

È possibile utilizzare solo un'attività, ma sarà necessario gestire il backstack quando si è in posizione verticale.

Nel descrivere il comportamento delle app, ci potrebbero essere 4 stati:

  • Stato A: ritratto, che mostra il frammento lista.
  • Stato B: ritratto, che mostra il frammento di dettagli con il frammento di elenco nello stack posteriore.
  • Stato C: orizzontale, che mostra il frammento di elenco sulla sinistra e uno spazio vuoto sulla destra.
  • Stato D: orizzontale, che mostra il frammento dell'elenco e il frammento di dettagli affiancati.

Immaginate di essere nello stato D (con entrambi i frammenti, chiamiamoli FA e FB) e di modificare l'orientamento del telefono. Lo stato seguente dovrebbe essere lo stato B, ma il problema è che il layout verticale ha solo uno FrameLayout. Utilizzando il seguente come il layout singolo riquadro:

<?xml version="1.0" encoding="utf-8"?> 
<FrameLayout android:id="@+id/list" ... /> 

Android ricreerà FA e dovrà attaccato a quella FrameLayout. L'FB, d'altra parte, verrà ricreato ma non avrà un contenitore associato, quindi non verrà visualizzato. A questo punto è possibile creare un altro frammento, FB2 con lo stesso contenuto di FB e utilizzarlo per sostituire FA. Avrai FA-FB2 nel tuo backstack e FB nascosto.

Se si modifica nuovamente l'orientamento (in attesa dello stato D), è possibile utilizzare onSaveInstanceState() per inserire l'FB2 dal backstack con popBackStack(), ottenendo così nuovamente FA e FB. Prima di rimuovere FB2, potresti anche voler copiare il suo contenuto in FB. Quando l'app è di nuovo nello stato D, FB avrà il suo FrameLayout.

Ci sarebbero alcune altre transizioni e situazioni di cui dovresti occuparti, ma l'idea principale sarebbe quella.

Non è una soluzione molto elegante, quindi sono sicuro che deve essere un modo migliore, forse più efficiente (senza replicare Fragments ad esempio) per risolvere questo problema.

Problemi correlati