Das Layout mit dem unterstützenden Bereich sorgt dafür, dass der Fokus des Nutzers auf den Hauptinhalten der App bleibt, während relevante unterstützende Informationen angezeigt werden. Im Hauptbereich können beispielsweise Details zu einem Film angezeigt werden, während im unterstützenden Bereich ähnliche Filme, Filme desselben Regisseurs oder Werke mit denselben Schauspielern aufgeführt werden.
Weitere Informationen finden Sie in den Richtlinien für unterstützende Bereiche in Material 3.
Unterstützenden Bereich mit einem Scaffold implementieren
NavigableSupportingPaneScaffold ist ein Composable, das die Implementierung eines Layouts mit unterstützendem Bereich in Jetpack Compose vereinfacht. Es umschließt
SupportingPaneScaffold und fügt eine integrierte Navigation und die Verarbeitung der intelligenten „Zurück“-Touchgeste
hinzu.
Ein unterstützender Bereich kann bis zu drei Bereiche enthalten:
- Hauptbereich: Hier werden die primären Inhalte angezeigt.
- Unterstützender Bereich: Hier werden zusätzlicher Kontext oder Tools im Zusammenhang mit dem Hauptbereich bereitgestellt.
- Zusätzlicher Bereich (optional): Wird bei Bedarf für zusätzliche Inhalte verwendet.
Das Scaffold wird an die Fenstergröße angepasst:
- In großen Fenstern werden der Hauptbereich und der unterstützende Bereich nebeneinander angezeigt.
In kleinen Fenstern ist jeweils nur ein Bereich sichtbar. Die Bereiche werden gewechselt, wenn Nutzer navigieren.
Abbildung 1 Layout mit unterstützendem Bereich
Abhängigkeiten hinzufügen
NavigableSupportingPaneScaffold ist Teil der adaptiven Layoutbibliothek von Material 3.
Fügen Sie der Datei build.gradle Ihrer App oder Ihres Moduls die folgenden drei zugehörigen Abhängigkeiten hinzu:
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'
adaptiv: Bausteine auf niedriger Ebene wie
HingeInfoundPostureadaptive-layout: Adaptive Layouts wie
ListDetailPaneScaffoldundSupportingPaneScaffoldadaptive-navigation: Composables für die Navigation innerhalb und zwischen Bereichen sowie adaptive Layouts, die standardmäßig die Navigation unterstützen, z. B.
NavigableListDetailPaneScaffoldundNavigableSupportingPaneScaffold
Prüfen Sie, ob Ihr Projekt die Version 1.1.0-beta1 oder höher von compose-material3-adaptive enthält.
Intelligente „Zurück“-Touchgeste aktivieren
Wenn Sie Animationen für die intelligente „Zurück“-Touchgeste in Android 15 oder niedriger aktivieren möchten, müssen Sie die Unterstützung für diese Touchgeste aktivieren. Fügen Sie dazu in der Datei AndroidManifest.xml dem Tag <application> oder
einzelnen <activity> Tags
android:enableOnBackInvokedCallback="true" hinzu.
Wenn Ihre App auf Android 16 (API‑Level 36) oder höher ausgerichtet ist, ist die intelligente „Zurück“-Touchgeste standardmäßig aktiviert.
Navigator erstellen
In kleinen Fenstern wird jeweils nur ein Bereich angezeigt. Verwenden Sie daher einen
ThreePaneScaffoldNavigator, um zwischen den Bereichen zu wechseln. Erstellen Sie eine Instanz
des Navigators mit rememberSupportingPaneScaffoldNavigator.
val scaffoldNavigator = rememberSupportingPaneScaffoldNavigator() val scope = rememberCoroutineScope()
Navigator an das Scaffold übergeben
Das Scaffold erfordert einen ThreePaneScaffoldNavigator, eine Schnittstelle
, die den Status des Scaffolds, den ThreePaneScaffoldValue und eine
PaneScaffoldDirective darstellt.
NavigableSupportingPaneScaffold( navigator = scaffoldNavigator, mainPane = { /*...*/ }, supportingPane = { /*...*/ }, )
Der Hauptbereich und der unterstützende Bereich sind Composables, die Ihre Inhalte enthalten. Verwenden Sie
AnimatedPane, um die Standardanimationen für Bereiche während der Navigation anzuwenden. Verwenden Sie
den Scaffold-Wert, um zu prüfen, ob der unterstützende Bereich ausgeblendet ist. Wenn dies der Fall ist,
zeigen Sie eine Schaltfläche an, mit der
navigateTo(SupportingPaneScaffoldRole.Supporting) aufgerufen wird, um den
unterstützenden Bereich anzuzeigen.
Verwenden Sie für große Bildschirme die ThreePaneScaffoldNavigator.navigateBack()
Methode, um den unterstützenden Bereich zu schließen. Übergeben Sie dabei die
BackNavigationBehavior.PopUntilScaffoldValueChange Konstante. Durch den Aufruf dieser
Methode wird eine Neuzusammensetzung von NavigableSupportingPaneScaffold erzwungen.
Prüfen Sie während der Neuzusammensetzung die
ThreePaneScaffoldNavigator.currentDestination Eigenschaft, um zu ermitteln,
ob der unterstützende Bereich angezeigt werden soll.
Hier ist eine vollständige Implementierung des Scaffolds:
val scaffoldNavigator = rememberSupportingPaneScaffoldNavigator() val scope = rememberCoroutineScope() val backNavigationBehavior = BackNavigationBehavior.PopUntilScaffoldValueChange NavigableSupportingPaneScaffold( navigator = scaffoldNavigator, mainPane = { AnimatedPane( modifier = Modifier .safeContentPadding() .background(Color.Red) ) { if (scaffoldNavigator.scaffoldValue[SupportingPaneScaffoldRole.Supporting] == PaneAdaptedValue.Hidden) { Button( modifier = Modifier .wrapContentSize(), onClick = { scope.launch { scaffoldNavigator.navigateTo(SupportingPaneScaffoldRole.Supporting) } } ) { Text("Show supporting pane") } } else { Text("Supporting pane is shown") } } }, supportingPane = { AnimatedPane(modifier = Modifier.safeContentPadding()) { Column { // Allow users to dismiss the supporting pane. Use back navigation to // hide an expanded supporting pane. if (scaffoldNavigator.scaffoldValue[SupportingPaneScaffoldRole.Supporting] == PaneAdaptedValue.Expanded) { // Material design principles promote the usage of a right-aligned // close (X) button. IconButton( modifier = Modifier.align(Alignment.End).padding(16.dp), onClick = { scope.launch { scaffoldNavigator.navigateBack(backNavigationBehavior) } } ) { Icon(Icons.Default.Close, contentDescription = "Close") } } Text("Supporting pane") } } } )
Composable für Bereiche extrahieren
Extrahieren Sie die einzelnen Bereiche eines SupportingPaneScaffold in eigene Composables, damit sie wiederverwendbar und testbar sind. Verwenden Sie ThreePaneScaffoldScope
um auf AnimatedPane zuzugreifen, wenn Sie die Standardanimationen verwenden möchten:
@OptIn(ExperimentalMaterial3AdaptiveApi::class) @Composable fun ThreePaneScaffoldPaneScope.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") } } } @OptIn(ExperimentalMaterial3AdaptiveApi::class) @Composable fun ThreePaneScaffoldPaneScope.SupportingPane( scaffoldNavigator: ThreePaneScaffoldNavigator<Any>, modifier: Modifier = Modifier, backNavigationBehavior: BackNavigationBehavior = BackNavigationBehavior.PopUntilScaffoldValueChange, ) { val scope = rememberCoroutineScope() AnimatedPane(modifier = Modifier.safeContentPadding()) { Column { // Allow users to dismiss the supporting pane. Use back navigation to // hide an expanded supporting pane. if (scaffoldNavigator.scaffoldValue[SupportingPaneScaffoldRole.Supporting] == PaneAdaptedValue.Expanded) { // Material design principles promote the usage of a right-aligned // close (X) button. IconButton( modifier = modifier.align(Alignment.End).padding(16.dp), onClick = { scope.launch { scaffoldNavigator.navigateBack(backNavigationBehavior) } } ) { Icon(Icons.Default.Close, contentDescription = "Close") } } Text("Supporting pane") } } }
Durch das Extrahieren der Bereiche in Composables wird die Verwendung von SupportingPaneScaffold vereinfacht. Vergleichen Sie dazu die folgende Implementierung mit der vollständigen Implementierung des Scaffolds im vorherigen Abschnitt:
val scaffoldNavigator = rememberSupportingPaneScaffoldNavigator() val scope = rememberCoroutineScope() NavigableSupportingPaneScaffold( navigator = scaffoldNavigator, mainPane = { MainPane( shouldShowSupportingPaneButton = scaffoldNavigator.scaffoldValue.secondary == PaneAdaptedValue.Hidden, onNavigateToSupportingPane = { scope.launch { scaffoldNavigator.navigateTo(ThreePaneScaffoldRole.Secondary) } } ) }, supportingPane = { SupportingPane(scaffoldNavigator = scaffoldNavigator) }, )
Wenn Sie mehr Kontrolle über bestimmte Aspekte des Scaffolds benötigen, sollten Sie
SupportingPaneScaffold anstelle von NavigableSupportingPaneScaffold verwenden. Dabei
werden PaneScaffoldDirective und ThreePaneScaffoldValue oder
ThreePaneScaffoldState separat akzeptiert. Diese Flexibilität ermöglicht es Ihnen, benutzerdefinierte Logik für den Abstand zwischen den Bereichen zu implementieren und festzulegen, wie viele Bereiche gleichzeitig angezeigt werden sollen. Sie können auch die Unterstützung für die intelligente „Zurück“-Touchgeste aktivieren, indem Sie ThreePaneScaffoldPredictiveBackHandler hinzufügen.
ThreePaneScaffoldPredictiveBackHandler hinzufügen
Fügen Sie den Handler für die intelligente „Zurück“-Touchgeste hinzu, der eine Scaffold-Navigator-Instanz verwendet, und geben Sie das backBehavior an. Dadurch wird festgelegt, wie Ziele während der Rückwärtsnavigation aus dem Backstack entfernt werden. Übergeben Sie dann scaffoldDirective und scaffoldState an SupportingPaneScaffold. Verwenden Sie die Überladung, die ein ThreePaneScaffoldState akzeptiert, und übergeben Sie scaffoldNavigator.scaffoldState.
Definieren Sie den Hauptbereich und den unterstützenden Bereich in SupportingPaneScaffold. Verwenden Sie AnimatedPane für die Standardanimationen für Bereiche.
Nachdem Sie diese Schritte ausgeführt haben, sollte Ihr Code in etwa so aussehen:
val scaffoldNavigator = rememberSupportingPaneScaffoldNavigator() val scope = rememberCoroutineScope() ThreePaneScaffoldPredictiveBackHandler( navigator = scaffoldNavigator, backBehavior = BackNavigationBehavior.PopUntilScaffoldValueChange ) SupportingPaneScaffold( directive = scaffoldNavigator.scaffoldDirective, scaffoldState = scaffoldNavigator.scaffoldState, mainPane = { MainPane( shouldShowSupportingPaneButton = scaffoldNavigator.scaffoldValue.secondary == PaneAdaptedValue.Hidden, onNavigateToSupportingPane = { scope.launch { scaffoldNavigator.navigateTo(ThreePaneScaffoldRole.Secondary) } } ) }, supportingPane = { SupportingPane(scaffoldNavigator = scaffoldNavigator) }, )