Układ panelu pomocniczego pozwala użytkownikowi skupić się na głównej treści aplikacji, jednocześnie wyświetlając istotne informacje pomocnicze. Na przykład w panelu głównym mogą wyświetlać się szczegóły filmu, a w panelu pomocniczym – podobne filmy, filmy tego samego reżysera lub dzieła z udziałem tych samych aktorów.
Więcej informacji znajdziesz w wytycznych dotyczących panelu wsparcia Material 3.
Implementowanie panelu pomocniczego za pomocą klasy bazowej NavigableSupportingPaneScaffold
NavigableSupportingPaneScaffold
to komponent, który upraszcza implementowanie układu panelu pomocniczego w Jetpack Compose. Opisuje ona klasę SupportingPaneScaffold
i dodaje wbudowaną nawigację oraz obsługę przewidywania wstecz.
Szkielet panelu pomocniczego obsługuje maksymalnie 3 panele:
- Panel główny: wyświetla główną zawartość.
- Panel pomocniczy: zawiera dodatkowe informacje lub narzędzia związane z głównym panelem.
- Dodatkowy panel (opcjonalnie): służy do wyświetlania dodatkowych treści w razie potrzeby.
Szablon dostosowuje się do rozmiaru okna:
- W dużych oknach panel główny i panel pomocniczy są wyświetlane obok siebie.
W małych oknach widoczna jest tylko jedna karta, która zmienia się w miarę poruszania się użytkownika.
Rysunek 1. Obsługa układu panelu.
Dodawanie zależności
NavigableSupportingPaneScaffold
jest częścią biblioteki Material 3 z dopasowywaniem układu.
Dodaj do pliku build.gradle
aplikacji lub modułu te 3 powiązane zależności:
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: elementy składowe niskiego poziomu, takie jak
HingeInfo
iPosture
; - adaptive-layout: układy adaptacyjne, takie jak
ListDetailPaneScaffold
iSupportingPaneScaffold
- adaptive-navigation: komponenty do nawigacji w ramkach i między nimi, a także elastyczne układy, które domyślnie obsługują nawigację, takie jak
NavigableListDetailPaneScaffold
iNavigableSupportingPaneScaffold
.
Upewnij się, że projekt zawiera pakiet compose-material3-adaptive w wersji 1.1.0-beta1 lub nowszej.
Włączanie gestu przewidywanego przejścia wstecz
Aby włączyć animacje przewidywanego przejścia wstecz w Androidzie 15 lub starszym, musisz wyrazić zgodę na obsługę gestu przewidywanego przejścia wstecz. Aby włączyć tę funkcję, dodaj tag android:enableOnBackInvokedCallback="true"
do tagu <application>
[tag] lub tag android:enableOnBackInvokedCallback="true"
do tagu <application>
lub do tagów <activity>
w pliku AndroidManifest.xml
.
Gdy Twoja aplikacja jest kierowana na Androida 16 (poziom interfejsu API 36) lub nowszego, przewidywane cofnięcie jest domyślnie włączone.
Tworzenie nawigatora
W małych oknach wyświetlana jest tylko jedna karta, więc do przełączania się między nimi używaj przycisku ThreePaneScaffoldNavigator
. Utwórz instancję nawigatora za pomocą funkcji rememberSupportingPaneScaffoldNavigator
.
val scaffoldNavigator = rememberSupportingPaneScaffoldNavigator() val scope = rememberCoroutineScope()
Przekazywanie nawigatora do szablonu
Szablon wymaga interfejsu ThreePaneScaffoldNavigator
, który reprezentuje stan szablonu, ThreePaneScaffoldValue
i PaneScaffoldDirective
.
NavigableSupportingPaneScaffold( navigator = scaffoldNavigator, mainPane = { /*...*/ }, supportingPane = { /*...*/ }, )
Panel główny i panel pomocniczy to elementy składowe zawierające Twoje treści. Użyj opcji AnimatedPane
, aby zastosować domyślne animacje paneli podczas nawigacji. Użyj wartości szablonu, aby sprawdzić, czy panel pomocniczy jest ukryty. Jeśli tak, wyświetl przycisk, który wywołuje funkcję navigateTo(SupportingPaneScaffoldRole.Supporting)
, aby wyświetlić panel pomocniczy.
Oto pełna implementacja szablonu:
val scaffoldNavigator = rememberSupportingPaneScaffoldNavigator() val scope = rememberCoroutineScope() 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()) { Text("Supporting pane") } } )
Elementy kompozytowe w panelu Extract
Wyodrębnij poszczególne panele SupportingPaneScaffold
w osobne komponenty, aby można było ich używać wielokrotnie i testować. Aby uzyskać dostęp do AnimatedPane
, użyj ThreePaneScaffoldScope
, jeśli chcesz używać domyślnych animacji:
@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( modifier: Modifier = Modifier, ) { AnimatedPane(modifier = modifier.safeContentPadding()) { // Supporting pane content Text("This is the supporting pane") } }
Wyodrębnienie paneli w elementy składane upraszcza korzystanie z SupportingPaneScaffold
(porównaj to z pełną implementacją szablonu w poprzedniej sekcji):
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() }, )
Jeśli potrzebujesz większej kontroli nad określonymi aspektami szablonu, użyj SupportingPaneScaffold
zamiast NavigableSupportingPaneScaffold
. Ta funkcja akceptuje PaneScaffoldDirective
i ThreePaneScaffoldValue
lub ThreePaneScaffoldState
osobno. Ta elastyczność umożliwia implementowanie niestandardowej logiki dla odstępów między panelami i określanie, ile paneli ma być wyświetlanych jednocześnie. Możesz też włączyć funkcję przewidywania cofnięcia, dodając ThreePaneScaffoldPredictiveBackHandler
.
Dodaj ThreePaneScaffoldPredictiveBackHandler
Dołącz moduł obsługi przewidywanego przejścia wstecz, który przyjmuje instancję szablonu nawigatora, i określ backBehavior
. Określa sposób, w jaki miejsca docelowe są usuwane z backstacka podczas nawigacji wstecz. Następnie prześlij scaffoldDirective
i scaffoldState
do SupportingPaneScaffold
. Użyj przeciążenia, które akceptuje ThreePaneScaffoldState
, przekazując scaffoldNavigator.scaffoldState
.
Określ główne i pomocnicze panele w SupportingPaneScaffold
. Użyj opcji
AnimatedPane
, aby ustawić domyślne animacje paneli.
Po wykonaniu tych czynności kod powinien wyglądać mniej więcej tak:
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() }, )