Utwórz układ panelu pomocniczego

Kanoniczny układ panelu pomocniczego skupia uwagę użytkownika na głównej treści aplikacji, a zarazem wyświetla odpowiednie treści pomocnicze. Na przykład w panelu głównym treści mogą się wyświetlać informacje o ostatnio dodanych filmach, a w panelu pomocniczym lista innych filmów o podobnej tematyce lub z tym samym reżyserem lub aktorami. Więcej informacji o kanonicznym układzie panelu pomocniczego znajdziesz w wytycznych dotyczących panelu pomocniczego w Material Design 3.

Implementacja panelu pomocniczego

SupportingPaneScaffold ma maksymalnie 3 panele: panel główny, panel pomocniczy i opcjonalny panel dodatkowy. Szablon obsługuje wszystkie obliczenia dotyczące przydzielenia miejsca w oknie 3 panelom. Na dużych ekranach widoczny jest panel główny, a panel pomocniczy znajduje się z bok. Na małych ekranach wyświetla się pełny ekran głównego lub pomocniczego panelu.

Główna treść zajmująca większość ekranu, a obok niej znajduje się dodatkowa treść.
Rysunek 1. Obsługa układu panelu.

Dodawanie zależności

SupportingPaneScaffold jest częścią biblioteki układu adaptacyjnego Material 3.

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 i Posture.
  • Układ adaptacyjny – układy adaptacyjne, takie jak SupportingPaneScaffold
  • adaptive-navigation – komponenty do nawigacji w obrębie paneli i między nimi

Tworzenie nawigatora i szkieletu

W małych oknach wyświetla się tylko 1 panel naraz, dlatego do przechodzenia do i z okien używaj ThreePaneScaffoldNavigator. Utwórz instancję nawigatora za pomocą funkcji rememberSupportingPaneScaffoldNavigator. Aby obsłużyć gesty wstecz, użyj BackHandler, który sprawdza canNavigateBack() i wywołuje navigateBack():

val navigator = rememberSupportingPaneScaffoldNavigator()

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

Szablon wymaga parametru PaneScaffoldDirective, który określa sposób podziału ekranu i odstępy między panelami, oraz parametru ThreePaneScaffoldValue, który określa bieżący stan paneli (np. czy są one rozszerzone czy ukryte). Domyślne działanie: scaffoldDirective i scaffoldValue:

SupportingPaneScaffold(
    directive = navigator.scaffoldDirective,
    value = navigator.scaffoldValue,
    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(ThreePaneScaffoldRole.Secondary), aby wyświetlić panel pomocniczy.

Oto pełna implementacja szablonu:

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")
        }
    },
)

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, gdy chcesz używać domyślnych animacji, kliknij ThreePaneScaffoldScope:

@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")
    }
}

Wyodrębnienie paneli w elementy składane upraszcza korzystanie z SupportingPaneScaffold (porównaj to z pełną implementacją szablonu w poprzedniej sekcji):

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() },
)