Layout da tavolo con griglia e mediaQuery

Icona di valutazione a 4 stelle

La postura da tavolo sui dispositivi pieghevoli divide un singolo schermo in due aree di visualizzazione funzionali separate dalla piega fisica (o dalla cerniera). La postura da tavolo ti consente di posizionare i contenuti principali della tua app (come un video player o un canvas di gioco) nella metà superiore, mentre gli elementi interattivi (come i controlli multimediali o i pad di controllo) nella metà inferiore.

Dispositivo pieghevole in posizione orizzontale che mostra contenuti video sullo schermo superiore e controlli di riproduzione sullo schermo inferiore.
Figura 1. La postura da tavolo divide i contenuti e i controlli interattivi sulla piega fisica.

Best practice

Per aggiungere il supporto della postura da tavolo alla tua app, utilizza l'API Grid per definire un layout con due righe e una colonna e applica la media query della postura della finestra da tavolo.

  • Rileva la postura da tavolo in modo reattivo: utilizza il mediaQuery composable per osservare lo stato del dispositivo. Quando il dispositivo è piegato in postura da tavolo (windowPosture == Posture.Tabletop), sposta dinamicamente il layout senza richiedere riavvii dell'attività o una gestione complessa del ciclo di vita.
  • Struttura i layout con Grid: quando è in postura da tavolo, utilizza l'API Grid (2 rows, 1 column) per separare chiaramente i contenuti visivi principali nella riga superiore above the fold e i controlli interattivi nella riga inferiore below the fold.
  • Sfrutta l'indicizzazione Z implicita per le sovrapposizioni: nelle posture standard (non da tavolo), assegna più ID area alla stessa cella per sovrapporre i controlli al player. Grid esegue automaticamente il rendering degli elementi da dietro in avanti nell'ordine di dichiarazione.
  • Fornisci transizioni fluide: assicurati che lo stato e le posizioni di scorrimento vengano mantenuti durante la transizione tra i layout standard a schermo intero e la postura da tavolo.

Ingredienti

  • Grid: un container di layout adattivo che ti consente di posizionare gli elementi in righe e colonne configurabili, ideale per dividere i contenuti in regioni dello schermo distinte.
  • mediaQuery: un'API Jetpack Compose utilizzata per eseguire query sulla postura, sulle classi di dimensioni e sulle caratteristiche hardware della finestra corrente dell'app direttamente all'interno dei composable.

Passaggi

Esegui una query sulla postura del dispositivo utilizzando mediaQuery(). Quando il dispositivo è in postura da tavolo, disponi i contenuti dell'app in una griglia verticale con due righe e una colonna, assicurandoti che i contenuti principali rimangano in alto e che i controlli rimangano accessibili in basso.

1. Definisci le configurazioni della griglia per la modalità da tavolo

All'interno di una funzione composable, definisci gli ID delle aree di layout utilizzando un'enumerazione e configura i blocchi GridConfigurationScope per le posture predefinite e da tavolo.

In defaultConfig, entrambe le aree vengono assegnate alla stessa cella (row = 1, column = 1). Grid utilizza l'indicizzazione Z implicita in cui i composable dichiarati in un secondo momento nel layout vengono sottoposti a rendering sopra quelli precedenti, consentendo al controller di sovrapporsi al player senza nidificazione di container aggiuntiva (per maggiori dettagli, consulta Sovrapposizioni di elementi UI con la griglia).

enum class VideoPlayerArea { Player, Controller }

object PlayerGridConfig {
    // Default: Single area layout with overlay (controls on top of player)
    val defaultConfig: GridConfigurationScope.() -> Unit = {
        row(1f)
        column(1f)
        area(areaId = VideoPlayerArea.Player, row = 1, column = 1)
        area(areaId = VideoPlayerArea.Controller, row = 1, column = 1)
    }

    // Tabletop: Two rows splitting content across the fold
    val tabletopConfig: GridConfigurationScope.() -> Unit = {
        row(0.5f)
        row(0.5f)
        column(1f)
        area(areaId = VideoPlayerArea.Player, row = 1, column = 1) // Top half above fold
        area(areaId = VideoPlayerArea.Controller, row = 2, column = 1) // Bottom half below fold
    }
}

2. Rileva la postura da tavolo e applica la configurazione alla griglia

Utilizza mediaQuery per selezionare la configurazione attiva in base a windowPosture, passa config a Grid e associa i contenuti composable agli ID area. La dichiarazione di VideoPlayerArea.Player prima di VideoPlayerArea.Controller garantisce che, quando entrambi condividono una cella in defaultConfig, i controlli vengano sottoposti a rendering sopra il player:

val config = mediaQuery {
    when (windowPosture) {
        Posture.Tabletop -> PlayerGridConfig.tabletopConfig
        else -> PlayerGridConfig.defaultConfig
    }
}

Grid(config = config) {
    Box(
        modifier = Modifier
            .gridItem(areaId = VideoPlayerArea.Player)
    ) {
        // VideoPlayerContent
    }

    Box(
        modifier = Modifier
            .gridItem(areaId = VideoPlayerArea.Controller)
    ) {
        // PlaybackControlsContent
    }
}

Risultati

Combinando mediaQuery e Grid, la tua app rileva dinamicamente quando un dispositivo pieghevole è parzialmente piegato in postura da tavolo e regola automaticamente la sua UI in due aree di visualizzazione funzionali divise dalla piega.

Risorse aggiuntive