Crea un layout per i riquadri di supporto

Il layout canonico del riquadro di supporto attira l'attenzione dell'utente sui contenuti principali della tua app, mostrando al contempo contenuti di supporto pertinenti. Ad esempio, il riquadro dei contenuti principale potrebbe mostrare informazioni su un film recente, mentre il riquadro di supporto potrebbe mostrare un elenco di altri film che hanno un tema simile o lo stesso regista o gli stessi attori con protagonisti. Per ulteriori informazioni sul layout canonico del riquadro di supporto, consulta le linee guida per il riquadro di supporto di Material 3.

Implementare un riquadro di supporto

SupportingPaneScaffold è composto da un massimo di tre riquadri: un riquadro principale, un riquadro di supporto e un riquadro aggiuntivo facoltativo. La struttura preliminare gestisce tutti i calcoli per l'allocazione dello spazio della finestra ai tre riquadri. Sugli schermi di grandi dimensioni, lo scafo mostra il riquadro principale con il riquadro di supporto a lato. Sugli schermi di piccole dimensioni, lo scaffold visualizza lo schermo intero principale o di supporto.

Contenuti principali che occupano la maggior parte dello spazio di visualizzazione con contenuti di supporto a lato.
Figura 1. Supporto del layout del riquadro.

Aggiungi dipendenze

SupportingPaneScaffold fa parte della libreria di layout adattivi Material 3.

Aggiungi le tre dipendenze correlate seguenti al file build.gradle della tua app o del tuo modulo:

Kotlin


implementation("androidx.compose.material3.adaptive:adaptive")
implementation("androidx.compose.material3.adaptive:adaptive-layout")
implementation("androidx.compose.material3.adaptive:adaptive-navigation")

Groovy


implementation 'androidx.compose.material3.adaptive:adaptive'
implementation 'androidx.compose.material3.adaptive:adaptive-layout'
implementation 'androidx.compose.material3.adaptive:adaptive-navigation'

  • adaptive: componenti di base di basso livello come HingeInfo e Posture
  • adaptive-layout: i layout adattivi, ad esempio SupportingPaneScaffold
  • adaptive-navigation: composabili per la navigazione all'interno e tra i riquadri

Creare un navigatore e uno scafo

Nelle finestre piccole viene visualizzato un solo riquadro alla volta, quindi utilizza ThreePaneScaffoldNavigator per spostarti tra i riquadri. Crea un'istanza del navigatore con rememberSupportingPaneScaffoldNavigator. Per gestire i gesti Indietro, utilizza un BackHandler che controlla canNavigateBack() e chiama navigateBack():

val navigator = rememberSupportingPaneScaffoldNavigator()

BackHandler(navigator.canNavigateBack()) {
    navigator.navigateBack()
}

Lo scaffold richiede un elemento PaneScaffoldDirective, che controlla come dividere lo schermo e quanta spaziatura utilizzare, e un ThreePaneScaffoldValue, che fornisce lo stato attuale dei riquadri (ad esempio se sono espansi o nascosti). Per il comportamento predefinito, utilizza rispettivamente scaffoldDirective e scaffoldValue del navigatore:

SupportingPaneScaffold(
    directive = navigator.scaffoldDirective,
    value = navigator.scaffoldValue,
    mainPane = { /*...*/ },
    supportingPane = { /*...*/ },
)

Il riquadro principale e il riquadro di supporto sono componibili che contengono i tuoi contenuti. Utilizza AnimatedPane per applicare le animazioni predefinite dei riquadri durante la navigazione. Utilizza il valore dello scaffold per verificare se il riquadro di supporto è nascosto; in questo caso, mostra un pulsante che chiami navigateTo(ThreePaneScaffoldRole.Secondary) per visualizzare il riquadro di supporto.

Ecco un'implementazione completa dello scaffold:

val navigator = rememberSupportingPaneScaffoldNavigator()

BackHandler(navigator.canNavigateBack()) {
    navigator.navigateBack()
}

SupportingPaneScaffold(
    directive = navigator.scaffoldDirective,
    value = navigator.scaffoldValue,
    mainPane = {
        AnimatedPane(modifier = Modifier.safeContentPadding()) {
            // Main pane content
            if (navigator.scaffoldValue[SupportingPaneScaffoldRole.Supporting] == PaneAdaptedValue.Hidden) {
                Button(
                    modifier = Modifier.wrapContentSize(),
                    onClick = {
                        navigator.navigateTo(SupportingPaneScaffoldRole.Supporting)
                    }
                ) {
                    Text("Show supporting pane")
                }
            } else {
                Text("Supporting pane is shown")
            }
        }
    },
    supportingPane = {
        AnimatedPane(modifier = Modifier.safeContentPadding()) {
            // Supporting pane content
            Text("Supporting pane")
        }
    },
)

Componenti composibili del riquadro Estrazione

Estrai i singoli riquadri di un SupportingPaneScaffold nei rispettivi composabili per renderli riutilizzabili e verificabili. Usa ThreePaneScaffoldScope per accedere a AnimatedPane se vuoi le animazioni predefinite:

@Composable
fun ThreePaneScaffoldScope.MainPane(
    shouldShowSupportingPaneButton: Boolean,
    onNavigateToSupportingPane: () -> Unit,
    modifier: Modifier = Modifier,
) {
    AnimatedPane(modifier = modifier.safeContentPadding()) {
        // Main pane content
        if (shouldShowSupportingPaneButton) {
            Button(onClick = onNavigateToSupportingPane) {
                Text("Show supporting pane")
            }
        } else {
            Text("Supporting pane is shown")
        }
    }
}

@Composable
fun ThreePaneScaffoldScope.SupportingPane(
    modifier: Modifier = Modifier,
) {
    AnimatedPane(modifier = modifier.safeContentPadding()) {
        // Supporting pane content
        Text("This is the supporting pane")
    }
}

L'estrazione dei riquadri in componenti composibili semplifica l'utilizzo di SupportingPaneScaffold (confronta quanto segue con l'implementazione completa dello scafo nella sezione precedente):

val navigator = rememberSupportingPaneScaffoldNavigator()

BackHandler(navigator.canNavigateBack()) {
    navigator.navigateBack()
}

SupportingPaneScaffold(
    directive = navigator.scaffoldDirective,
    value = navigator.scaffoldValue,
    mainPane = {
        MainPane(
            shouldShowSupportingPaneButton = navigator.scaffoldValue.secondary == PaneAdaptedValue.Hidden,
            onNavigateToSupportingPane = { navigator.navigateTo(ThreePaneScaffoldRole.Secondary) }
        )
    },
    supportingPane = { SupportingPane() },
)