Fai conoscere l'app

I display di grandi dimensioni quando sono aperti e gli stati di piegatura unici consentono nuove esperienze utente sui dispositivi pieghevoli. Per rendere la tua app compatibile con la piegatura in Jetpack Compose, utilizza la libreria Compose Material 3 Adaptive, che fornisce API per le funzionalità della finestra dei dispositivi pieghevoli, come pieghe, cerniere e posizioni del dispositivo. Quando la tua app è compatibile con la piegatura, può adattare il layout per evitare di posizionare contenuti importanti nell'area delle pieghe o delle cerniere e utilizzare pieghe e cerniere come separatori naturali.

Comprendere se un dispositivo supporta configurazioni come la posizione da tavolo o a libro può guidare le decisioni in merito al supporto di layout diversi o alla fornitura di funzionalità specifiche.

Informazioni sulla finestra

In Jetpack Compose, utilizza la funzione componibile collectFoldingFeaturesAsState() per osservare le informazioni sulla piegatura della finestra. collectFoldingFeaturesAsState() raccoglie le funzionalità di piegatura della finestra corrente da WindowInfoTracker in uno State di Compose contenente un elenco di FoldingFeature.

Poiché collectFoldingFeaturesAsState() restituisce uno State di Compose, i tuoi componibili vengono ricomposti automaticamente ogni volta che lo stato o la posizione della piegatura del dispositivo cambia, senza richiedere la gestione manuale del ciclo di vita o la raccolta del flusso:

@Composable
fun FoldAwareScreen() {
    val foldingFeatures by collectFoldingFeaturesAsState()

    // Access folding features for the current window.
    val foldFeature = foldingFeatures.firstOrNull()
    if (foldFeature != null) {
        // Adapt layout based on the fold feature.
    }
}

Funzionalità dei display pieghevoli

L'elenco degli elementi FoldingFeature restituiti da collectFoldingFeaturesAsState() (un sottotipo di DisplayFeature) fornisce informazioni sui display pieghevoli, incluse le seguenti proprietà:

  • state: lo stato di piegatura del dispositivo, FLAT o HALF_OPENED

  • orientation: l'orientamento della piega o della cerniera, HORIZONTAL o VERTICAL

  • occlusionType: indica se la piega o la cerniera nasconde una parte del display, NONE o FULL

  • isSeparating: indica se la piega o la cerniera crea due aree di visualizzazione logiche, true o false

Un dispositivo pieghevole HALF_OPENED segnala sempre isSeparating come true perché lo schermo è suddiviso in due aree di visualizzazione. Inoltre, isSeparating è sempre true su un dispositivo a doppio schermo quando l'applicazione si estende su entrambi gli schermi.

La proprietà FoldingFeature bounds (ereditata da DisplayFeature) rappresenta il rettangolo di delimitazione di una funzionalità di piegatura, ad esempio una piega o una cerniera. I limiti possono essere utilizzati per posizionare gli elementi sullo schermo rispetto alla funzionalità:

@Composable
fun FoldFeatureDemo() {
    val foldingFeatures by collectFoldingFeaturesAsState()
    val foldFeature = foldingFeatures.firstOrNull()

    if (foldFeature != null) {
        val isSeparating = foldFeature.isSeparating
        val occlusionType = foldFeature.occlusionType
        val bounds = foldFeature.bounds
        // Use bounds and properties to position content.
    }
}

Posizione da tavolo

Utilizzando le informazioni incluse nell'oggetto FoldingFeature, la tua app può supportare posizioni come quella da tavolo, in cui lo smartphone è appoggiato su una superficie, la cerniera è in posizione orizzontale e lo schermo pieghevole è aperto a metà.

La posizione da tavolo offre agli utenti la comodità di utilizzare lo smartphone senza tenerlo in mano. La posizione da tavolo è ideale per guardare contenuti multimediali, scattare foto ed effettuare videochiamate.

Un'app di video player in posizione orizzontale con riproduzione video nella
        parte verticale dello schermo e controlli di riproduzione nella
        parte orizzontale inferiore.
Figura 1. Un'app di video player in posizione da tavolo: video sulla parte verticale dello schermo; controlli di riproduzione sulla parte orizzontale.

Utilizza FoldingFeature.State e FoldingFeature.Orientation da collectFoldingFeaturesAsState() per determinare se il dispositivo è in posizione da tavolo postura:

@Composable
fun TabletopContent() {
    val foldingFeatures by collectFoldingFeaturesAsState()
    val foldFeature = foldingFeatures.firstOrNull()

    val isTableTopPosture = foldFeature != null &&
        foldFeature.state == FoldingFeature.State.HALF_OPENED &&
        foldFeature.orientation == FoldingFeature.Orientation.HORIZONTAL

    if (isTableTopPosture) {
        // Tabletop layout: separate content and controls across the fold.
    } else {
        // Standard layout.
    }
}

In alternativa, puoi determinare se la finestra è in posizione da tavolo controllando la proprietà Posture restituita da currentWindowAdaptiveInfoV2():

val adaptiveInfo = currentWindowAdaptiveInfoV2()
val isTabletop = adaptiveInfo.windowPosture.isTabletop

Una volta che sai che il dispositivo è in posizione da tavolo, aggiorna il layout dell'app di conseguenza. Per le app multimediali, in genere significa posizionare la riproduzione sopra la piega e posizionare i controlli e i contenuti supplementari subito dopo per un'esperienza di visualizzazione o ascolto senza mani.

Esempi

Posizione a libro

Un'altra funzionalità unica dei dispositivi pieghevoli è la posizione a libro, in cui il dispositivo è aperto a metà e la cerniera è verticale. La posizione a libro è ideale per leggere e-book. Con un layout a due pagine su un dispositivo pieghevole con schermo di grandi dimensioni aperto come un libro rilegato, la posizione a libro cattura l'esperienza di leggere un libro vero.

Può essere utilizzata anche per la fotografia se vuoi acquisire un rapporto di aspetto diverso mentre scatti foto senza mani.

Implementa la posizione a libro con le stesse tecniche utilizzate per la posizione da tavolo. Verifica che l'orientamento della funzionalità di piegatura sia verticale anziché orizzontale:

@Composable
fun BookContent() {
    val foldingFeatures by collectFoldingFeaturesAsState()
    val foldFeature = foldingFeatures.firstOrNull()

    val isBookPosture = foldFeature != null &&
        foldFeature.state == FoldingFeature.State.HALF_OPENED &&
        foldFeature.orientation == FoldingFeature.Orientation.VERTICAL

    if (isBookPosture) {
        // Book posture layout: two-page layout across the vertical fold.
    } else {
        // Standard single-page layout.
    }
}

Modifiche delle dimensioni della finestra

L'area di visualizzazione di un'app può cambiare a seguito di una modifica della configurazione del dispositivo, ad esempio quando il dispositivo viene piegato o aperto, ruotato o ridimensionato in modalità multi‑finestra.

Per recuperare la classe di dimensioni della finestra corrente e adattarti alle modifiche delle dimensioni in Jetpack Compose, utilizza la funzione componibile currentWindowAdaptiveInfoV2() della libreria Compose Material 3 Adaptive. currentWindowAdaptiveInfoV2() restituisce un'istanza WindowAdaptiveInfo che fornisce la WindowSizeClass della finestra corrente (con supporto per i punti di interruzione grandi ed extra-large per impostazione predefinita), nonché la windowPosture del dispositivo:

@Composable
fun AdaptiveApp() {
    val adaptiveInfo = currentWindowAdaptiveInfoV2()
    val windowSizeClass = adaptiveInfo.windowSizeClass

    when {
        windowSizeClass.isWidthAtLeastBreakpoint(
            WIDTH_DP_EXPANDED_LOWER_BOUND
        ) -> {
            // Expanded layout
        }
        windowSizeClass.isWidthAtLeastBreakpoint(
            WIDTH_DP_MEDIUM_LOWER_BOUND
        ) -> {
            // Medium layout
        }
        else -> {
            // Compact layout
        }
    }
}

Consulta Utilizzare le classi di dimensioni della finestra.

Risorse aggiuntive

Per scoprire di più sui layout compatibili con la piegatura e sui dispositivi pieghevoli, consulta le seguenti risorse:

Esempi

  • Esempio di Jetpack WindowManager: esempio di come utilizzare la libreria Jetpack WindowManager
  • Jetcaster : implementazione della posizione da tavolo con Compose

Codelab