Eseguire la migrazione dell'interfaccia utente ai layout adattabili

Le app Android devono supportare un ecosistema di fattori di forma dei dispositivi in continua espansione. L'interfaccia utente di un'app deve essere reattiva per adattarsi a schermi di varie dimensioni, nonché a orientamenti e stati dei dispositivi differenti.

La UI adattabile si basa sui principi di flessibilità e continuità.

Per flessibilità si intende i layout che sfruttano in modo ottimale lo spazio disponibile e si adeguano quando lo spazio disponibile viene modificato. Gli aggiustamenti possono assumere diverse forme: semplicemente aumentare le dimensioni di un'unica vista, riposizionare le viste in modo che siano in posizioni più accessibili, mostrare o nascondere visualizzazioni aggiuntive o una combinazione di queste.

Per continuità si intende un'esperienza utente senza interruzioni durante la transizione da una dimensione della finestra a un'altra. Qualunque sia l'esperienza in cui l'utente è coinvolto dovrebbe continuare senza interruzioni. Poiché una variazione delle dimensioni potrebbe essere accompagnata dall'eliminazione e dalla ricreazione dell'intera gerarchia delle visualizzazioni, è importante che l'utente non perda la posizione o i dati personali.

Cose da evitare

Evita di utilizzare valori hardware e fisici per prendere decisioni relative al layout. Si potrebbe avere la tentazione di prendere decisioni basate su un valore fisso, ma in molte situazioni questi valori non sono utili per determinare lo spazio con cui la UI può funzionare.

Sui tablet, un'app potrebbe essere in esecuzione in modalità multi-finestra, il che significa che l'app condivide lo schermo con un'altra app. Su ChromeOS, un'app potrebbe essere in una finestra ridimensionabile. Potrebbe anche esserci più di uno schermo fisico, ad esempio con un dispositivo pieghevole o un dispositivo con più display. In tutti questi casi, le dimensioni dello schermo fisico non sono pertinenti per decidere come visualizzare i contenuti.

Diversi dispositivi che mostrano finestre dell'app di dimensioni diverse.
Figura 1. Le dimensioni delle finestre possono essere diverse dalle dimensioni del dispositivo fisico o del display.

Per lo stesso motivo, evita di bloccare l'app su un orientamento o proporzioni specifiche. Anche se il dispositivo stesso può avere un orientamento particolare, l'app potrebbe avere un orientamento diverso esclusivamente in base alle dimensioni della finestra. Ad esempio, un'app può essere in verticale su un tablet in modalità Orizzontale in quanto più alta che larga.

Inoltre, evita di provare a stabilire se il dispositivo è uno smartphone o un tablet. Ciò che si qualifica in modo specifico come tablet è in qualche modo soggettivo: dipende dall'avere una dimensione, proporzioni o una combinazione di dimensioni e proporzioni? Man mano che emergono nuovi fattori di forma, queste ipotesi possono cambiare e la distinzione perde importanza.

Anziché provare una delle strategie precedenti, utilizza i punti di interruzione e le classi di dimensioni delle finestre.

Punti di interruzione e classi di dimensioni delle finestre

La parte effettiva della schermata assegnata alla tua app è la finestra dell'app. Potrebbe occupare tutto lo schermo o solo una parte, quindi ti consigliamo di valutare la dimensione della finestra quando prendi decisioni generali in merito al layout della tua app.

Quando progetti per più fattori di forma, trova i valori di soglia ai quali le decisioni di alto livello si diramano in direzioni diverse. A questo scopo, la griglia di layout adattabile di Material Design fornisce punti di interruzione per larghezza e altezza, che ti consentono di mappare le dimensioni non elaborate in gruppi standardizzati discreti, denominati classi delle dimensioni delle finestre. Data l'ubiquità dello scorrimento verticale, la maggior parte delle app interessa principalmente le classi delle dimensioni della larghezza, per cui molte app possono essere ottimizzate per tutte le dimensioni dello schermo gestendo solo pochi punti di interruzione. Per ulteriori informazioni sulle classi di dimensioni delle finestre, consulta Classi di dimensioni delle finestre.

Elementi UI permanenti

Le linee guida per il layout di Material Design definiscono le regioni per barre delle app, navigazione e contenuti. In genere, i primi due sono elementi UI permanenti nella radice (o molto vicina) alla radice della gerarchia delle viste. Tieni presente che "persistente" non significa necessariamente che la visualizzazione sia sempre visibile, ma piuttosto che rimane attiva mentre altre visualizzazioni dei contenuti potrebbero spostarsi o cambiare. Ad esempio, un elemento di navigazione potrebbe trovarsi in un cassetto a scomparsa fuori dallo schermo, ma con un cassetto sempre lì.

Gli elementi permanenti possono essere adattabili e di solito occupano l'intera larghezza o l'intera altezza della finestra, quindi preferisci utilizzare le classi di dimensioni per decidere dove posizionarli. che indica lo spazio rimanente per i contenuti. Nello snippet seguente, l'attività utilizza una barra inferiore per gli schermi compatti e una barra delle app superiore per gli schermi più grandi. I layout qualificati usano i punti di interruzione della larghezza come descritto in precedenza.

<!-- res/layout/main_activity.xml -->

<androidx.constraintlayout.widget.ConstraintLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <!-- content view(s) -->

    <com.google.android.material.bottomappbar.BottomAppBar
        android:layout_width="wrap_content"
        android:layout_height="0dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        ... />
</androidx.constraintlayout.widget.ConstraintLayout>


<!-- res/layout-w600dp/main_activity.xml -->
<androidx.constraintlayout.widget.ConstraintLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <com.google.android.material.appbar.AppBarLayout
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        ... />

    <!-- content view(s) -->
</androidx.constraintlayout.widget.ConstraintLayout>

Contenuti

Dopo aver posizionato gli elementi permanenti dell'interfaccia utente, utilizza lo spazio rimanente per i contenuti, ad esempio utilizzando un elemento NavHostFragment con il grafico di navigazione dell'app. Per ulteriori considerazioni, consulta Navigazione per le UI adattabili.

Assicurati che tutti i dati siano disponibili per dimensioni diverse

La maggior parte dei framework delle app oggi utilizza un modello di dati separato dai componenti Android che contribuiscono all'interfaccia utente (attività, frammenti e visualizzazioni). Con Jetpack, questo ruolo viene generalmente soddisfatto da ViewModels, che hanno il vantaggio aggiuntivo di essere sopravvissuti a tutte le modifiche alla configurazione (per ulteriori informazioni, consulta Panoramica di ViewModel).

Quando implementi un layout che si adatta a dimensioni diverse, potresti provare a utilizzare un modello di dati diverso in base alle dimensioni attuali. Tuttavia, questo è in contrasto con il principio del flusso di dati unidirezionale. I dati dovrebbero fluire verso il basso e gli eventi come le interazioni degli utenti dovrebbero fluire verso l'alto. La creazione di una dipendenza nell'altra direzione, in cui il modello dei dati dipende dalla configurazione del livello UI, complica notevolmente questo processo. Quando l'app cambia dimensione, devi tenere conto della conversione da un modello di dati a un altro.

Lascia invece che il tuo modello di dati soddisfi la classe di dimensioni più grande, poi puoi mostrare, nascondere o riposizionare selettivamente i contenuti nell'interfaccia utente per adattarli alla classe di dimensioni corrente. Di seguito sono riportate alcune strategie che puoi utilizzare per decidere come deve comportarsi il layout quando passi da una classe di dimensioni all'altra.

Espandi i contenuti

Layout canonici: feed

Lo spazio esteso può essere semplicemente un'opportunità per ingrandirli e riformattare i contenuti in modo da renderli più accessibili.

Ingrandisci le raccolte. Molte app mostrano una raccolta di elementi in un contenitore a scorrimento, ad esempio RecyclerView o ScrollView. Se consenti a un contenitore di ingrandire automaticamente le dimensioni, possono essere mostrati più contenuti. Tuttavia, assicurati che i contenuti all'interno del contenitore non risultino eccessivamente allungati o distorti. Ad esempio, con un elemento RecyclerView, valuta la possibilità di utilizzare uno strumento di gestione del layout diverso, come GridLayoutManager, StaggeredGridLayoutManager o FlexboxLayout, quando la larghezza non è compatta.

Un dispositivo piegato e aperto che mostra come i diversi gestori del layout dispongono l&#39;app in modo diverso a seconda della classe delle dimensioni della larghezza.
Figura 2. Gestori del layout diversi per classi di dimensioni delle finestre differenti.

I singoli elementi possono anche utilizzare una dimensione o una forma diverse per visualizzare più contenuti e distinguere più facilmente i confini degli elementi.

Evidenziare un elemento hero. Se il layout ha un punto focale particolare, ad esempio un'immagine o un video, espandilo quando la finestra dell'app si allunga per mantenere l'attenzione dell'utente. Altri elementi di supporto possono essere riorganizzati intorno o sotto la visualizzazione hero.

Esistono molti modi per creare un layout di questo tipo, ma ConstraintLayout è particolarmente adatto a questo scopo perché offre molti modi per vincolare le dimensioni di una vista figlio, tra cui in percentuale o per applicare le proporzioni, e per posizionare gli elementi secondari rispetto a se stesso o ad altri elementi secondari. Scopri di più su tutte queste funzionalità nella pagina Creare un'interfaccia utente adattabile con ConstraintLayout.

Mostra contenuti comprimibili per impostazione predefinita. Se c'è spazio disponibile, mostra contenuti che altrimenti sarebbero accessibili solo tramite l'interazione aggiuntiva dell'utente, come tocco, scorrimento o gesti. Ad esempio, i contenuti visualizzati in un'interfaccia a schede quando compatti potrebbero essere riorganizzati in colonne o in un elenco quando è disponibile più spazio.

Espandi i margini. Se lo spazio è così grande che non riesci a trovare una soluzione accattivante anche dopo aver utilizzato tutti i tuoi contenuti, espandi i margini del layout in modo che i contenuti rimangano centrati e le singole visualizzazioni abbiano dimensioni e spazi naturali tra loro.

In alternativa, un componente a schermo intero può trasformarsi in una UI di dialogo mobile. Questo è particolarmente adatto quando il componente richiede un'attenzione esclusiva per completare un'attività immediata dell'utente, come la scrittura di un'email o la creazione di un evento di calendario.

Uno smartphone standard che mostra una finestra di dialogo a schermo intero e uno smartphone pieghevole aperto che mostra la stessa finestra di dialogo di una finestra mobile.
Figura 3. Finestra di dialogo a schermo intero trasformata in una finestra di dialogo standard di larghezza media ed espansa.

Aggiungi contenuti

Layout canonici: riquadro di supporto, visualizzazione dettagli elenco

Utilizza un riquadro di supporto. Un riquadro di supporto presenta contenuti aggiuntivi o azioni contestuali relative ai contenuti principali, ad esempio commenti in un documento o elementi in una playlist. In genere, utilizzano il terzo inferiore dello schermo per l'altezza espansa o il terzo finale per la larghezza espansa.

Una considerazione importante riguarda il posizionamento di questi contenuti quando lo spazio non è sufficiente per mostrare il riquadro. Ecco alcune alternative da scoprire:

  • Riquadro a scomparsa laterale sul bordo finale che utilizza DrawerLayout
  • Riquadro a scomparsa inferiore utilizzando BottomSheetBehavior
  • Menu o finestra popup accessibile toccando un'icona del menu
Figura 4. Metodi alternativi per presentare contenuti aggiuntivi in un riquadro di supporto.

Crea un layout a due riquadri. Gli schermi di grandi dimensioni potrebbero mostrare una combinazione di funzionalità che in genere vengono visualizzate separatamente. Un pattern di interazione comune in molte app è mostrare un elenco di elementi, come contatti o risultati di ricerca, e passare ai dettagli di un elemento quando viene selezionato. Anziché ingrandire l'elenco per gli schermi più grandi, utilizza la visualizzazione dei dettagli dell'elenco per mostrare entrambe le funzionalità affiancate in un layout a due riquadri. A differenza di un riquadro di supporto, il riquadro dei dettagli di una visualizzazione dei dettagli elenco è un elemento autonomo che può essere mostrato in modo indipendente su schermi più piccoli.

Utilizza il widget dedicato SlidingPaneLayout per implementare una visualizzazione dei dettagli dell'elenco. Questo widget calcola automaticamente se è disponibile spazio sufficiente per visualizzare entrambi i riquadri in base al valore layout_width specificato per i due riquadri e l'eventuale spazio residuo può essere distribuito utilizzando layout_weight. Se lo spazio non è sufficiente, ogni riquadro utilizza l'intera larghezza del layout e il riquadro dei dettagli viene spostato fuori dallo schermo o sopra il riquadro dell'elenco.

SlidingPaneLayout che mostra entrambi i riquadri di un layout con dettagli elenco su un dispositivo con un display ampio.
Figura 5. SlidingPaneLayout che mostra due riquadri in larghezza espansa e un riquadro a larghezza compatta.

Crea un layout a due riquadri contiene maggiori dettagli sull'utilizzo di SlidingPaneLayout. Tieni inoltre presente che questo pattern può influire sulla struttura del grafico di navigazione (consulta la sezione Navigazione per le UI adattabili).

Risorse aggiuntive