Crea un layout per i riquadri di supporto

Il layout canonico del riquadro di supporto focalizza l'attenzione degli utenti 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 con un tema simile o lo stesso regista o attori protagonisti. Per ulteriori informazioni sul layout canonico dei riquadri di supporto, consulta le linee guida per i riquadri di supporto di Material 3.

Implementare un riquadro di supporto

SupportingPaneScaffold è costituito da massimo tre riquadri: un riquadro principale, un riquadro di supporto e un riquadro aggiuntivo facoltativo. Lo scaffold gestisce tutti i calcoli per allocare lo spazio delle finestre ai tre riquadri. Sugli schermi di grandi dimensioni, l'impalcatura mostra il riquadro principale con il riquadro di supporto sul lato. Su schermi di piccole dimensioni, l'impalcatura mostra il riquadro principale o di supporto a schermo intero.

Contenuti principali che occupano la maggior parte del display e contenuti di supporto a fianco.
Figura 1. Layout del riquadro di supporto.

Aggiungi dipendenze

SupportingPaneScaffold fa parte della libreria di layout adattivo Material 3.

Aggiungi le seguenti tre dipendenze correlate al file build.gradle dell'app o del modulo:

Kotlin


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

trendy


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

  • Adattivo: componenti di base di basso livello come HingeInfo e Posture
  • Layout adattivo: i layout adattivi, ad esempio SupportingPaneScaffold
  • Adaptive-navigation: elementi componibili per navigare all'interno e tra i riquadri

Crea un navigatore e un'impalcatura

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, usa una BackHandler che controlla canNavigateBack() e le chiamate navigateBack():

val navigator = rememberSupportingPaneScaffoldNavigator()

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

Lo scaffold richiede un elemento PaneScaffoldDirective, che controlla come suddividere lo schermo e la quantità di spazio da utilizzare, e un elemento ThreePaneScaffoldValue, che fornisce lo stato attuale dei riquadri (ad esempio se sono espansi o nascosti). Per il comportamento predefinito, utilizza rispettivamente i valori scaffoldDirective e scaffoldValue del navigatore:

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

Il riquadro principale e quello di supporto sono elementi componibili che includono i tuoi contenuti. Utilizza AnimatedPane per applicare le animazioni predefinite dei riquadri durante la navigazione. Utilizza il valore "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")
        }
    },
)

Estrai elementi componibili del riquadro

Estrai i singoli riquadri di un elemento SupportingPaneScaffold nei relativi componenti componibili per renderli riutilizzabili e testabili. Utilizza ThreePaneScaffoldScope per accedere a AnimatedPane se vuoi utilizzare 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 elementi componibili semplifica l'utilizzo di SupportingPaneScaffold (confronta quanto segue con l'implementazione completa dell'impalcatura 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() },
)