Większość aplikacji ma kilka miejsc docelowych najwyższego poziomu, które są dostępne w głównym interfejsie nawigacji aplikacji. W kompaktowych oknach, np. na standardowym wyświetlaczu telefonu, miejsca docelowe są zwykle wyświetlane na pasku nawigacyjnym u dołu okna. W rozszerzonym oknie, np. w przypadku aplikacji pełnoekranowej na tablecie, zwykle lepszym wyborem jest pasek nawigacyjny obok aplikacji, ponieważ łatwiej jest uzyskać dostęp do elementów sterujących nawigacji, przytrzymując lewą i prawą stronę urządzenia.
NavigationSuiteScaffold
upraszcza przełączanie się między interfejsami nawigacji, wyświetlając odpowiedni element kompozycyjny nawigacji na podstawie WindowSizeClass
. Obejmuje to dynamiczną zmianę interfejsu w przypadku zmiany rozmiaru okna w czasie działania. Domyślnym zachowaniem jest wyświetlanie jednego z tych komponentów interfejsu:
- paska nawigacyjnego, jeśli szerokość lub wysokość jest niewielka albo gdy urządzenie jest ustawione na stole;
- Kolejki nawigacyjne we wszystkich innych miejscach
Dodaj zależności
NavigationSuiteScaffold
jest częścią biblioteki pakietu nawigacji adaptacyjnej Material3. Dodaj zależność dla biblioteki w pliku build.gradle
aplikacji lub modułu:
Kotlin
implementation("androidx.compose.material3:material3-adaptive-navigation-suite")
Odlotowy
implementation 'androidx.compose.material3:material3-adaptive-navigation-suite'
Utwórz rusztowanie
Dwie główne części usługi NavigationSuiteScaffold
to elementy pakietu nawigacyjnego i treści dla wybranego miejsca docelowego. Elementy pakietu nawigacyjnego można definiować bezpośrednio w elemencie kompozycyjnym, ale często są one definiowane w innym miejscu, np. w wyliczeniu:
enum class AppDestinations( @StringRes val label: Int, val icon: ImageVector, @StringRes val contentDescription: Int ) { HOME(R.string.home, Icons.Default.Home, R.string.home), FAVORITES(R.string.favorites, Icons.Default.Favorite, R.string.favorites), SHOPPING(R.string.shopping, Icons.Default.ShoppingCart, R.string.shopping), PROFILE(R.string.profile, Icons.Default.AccountBox, R.string.profile), }
Aby użyć funkcji NavigationSuiteScaffold
, musisz śledzić bieżące miejsce docelowe. Możesz to zrobić, korzystając z usługi rememberSaveable
:
var currentDestination by rememberSaveable { mutableStateOf(AppDestinations.HOME) }
W tym przykładzie parametr navigationSuiteItems
(typ NavigationSuiteScope
używa swojej funkcji item
do definiowania interfejsu nawigacji w przypadku danego miejsca docelowego). Interfejs docelowy jest używany między paskami nawigacyjnymi, szynami i szufladami. Aby utworzyć elementy nawigacji, zapętlasz element AppDestinations
(zdefiniowany we wcześniejszym fragmencie):
NavigationSuiteScaffold( navigationSuiteItems = { AppDestinations.entries.forEach { item( icon = { Icon( it.icon, contentDescription = stringResource(it.contentDescription) ) }, label = { Text(stringResource(it.label)) }, selected = it == currentDestination, onClick = { currentDestination = it } ) } } ) { // TODO: Destination content. }
W obiekcie lambda zawartości docelowej użyj wartości currentDestination
, aby zdecydować, który interfejs ma się wyświetlać. Jeśli w swojej aplikacji używasz biblioteki nawigacji, użyj jej tutaj, aby wyświetlić odpowiednie miejsce docelowe. Kiedy wystarczy stwierdzenie:
NavigationSuiteScaffold( navigationSuiteItems = { /*...*/ } ) { // Destination content. when (currentDestination) { AppDestinations.HOME -> HomeDestination() AppDestinations.FAVORITES -> FavoritesDestination() AppDestinations.SHOPPING -> ShoppingDestination() AppDestinations.PROFILE -> ProfileDestination() } }
Zmień kolory
NavigationSuiteScaffold
tworzy element Surface
obejmujący cały obszar, który zajmuje rusztowanie, zwykle całe okno. Dodatkowo tworzy w nim odpowiedni interfejs nawigacyjny, na przykład NavigationBar
.
Zarówno platforma, jak i interfejs nawigacyjny używają wartości określonych w motywie aplikacji, ale możesz zastąpić wartości motywu.
Parametr containerColor
określa kolor powierzchni. Domyślnie jest to kolor tła schematu kolorów. Parametr contentColor
określa kolor treści na tej platformie. Domyślnym kolorem jest „włączony” przy wszystkich elementach określonych w polu containerColor
. Jeśli np. containerColor
używa koloru background
, contentColor
używa koloru onBackground
.
Więcej informacji o systemie kolorów znajdziesz w artykule Tworzenie motywów Material Design 3 w sekcji Utwórz. Aby zastąpić te wartości, użyj wartości zdefiniowanych w motywie, aby aplikacja obsługiwała ciemne i jasne tryby wyświetlania:
NavigationSuiteScaffold( navigationSuiteItems = { /* ... */ }, containerColor = MaterialTheme.colorScheme.primary, contentColor = MaterialTheme.colorScheme.onPrimary, ) { // Content... }
Interfejs nawigacji jest narysowany przed powierzchnią NavigationSuiteScaffold
.
Wartości domyślne kolorów interfejsu podaje NavigationSuiteDefaults.colors()
, ale możesz je też zastąpić. Jeśli np. tło paska nawigacyjnego ma być przezroczyste, ale pozostałe wartości mają pozostać domyślne, zastąp navigationBarContainerColor
:
NavigationSuiteScaffold( navigationSuiteItems = { /* ... */ }, navigationSuiteColors = NavigationSuiteDefaults.colors( navigationBarContainerColor = Color.Transparent, ) ) { // Content... }
W ostatecznym rozrachunku można dostosować każdy element w interfejsie nawigacji. Wywołując funkcję item
, możesz przekazać instancję NavigationSuiteItemColors
. Klasa określa kolory elementów paska nawigacyjnego, kolumnie nawigacyjnej i szuflady nawigacyjnej. Oznacza to, że każdy typ interfejsu nawigacji może mieć identyczne kolory lub kolory w zależności od potrzeb. Zdefiniuj kolory na poziomie NavigationSuiteScaffold
, aby używać tej samej instancji obiektu dla wszystkich elementów, i wywołaj funkcję NavigationSuiteDefaults.itemColors()
, aby zastąpić tylko te, które chcesz zmienić:
val myNavigationSuiteItemColors = NavigationSuiteDefaults.itemColors( navigationBarItemColors = NavigationBarItemDefaults.colors( indicatorColor = MaterialTheme.colorScheme.primaryContainer, selectedIconColor = MaterialTheme.colorScheme.onPrimaryContainer ), ) NavigationSuiteScaffold( navigationSuiteItems = { AppDestinations.entries.forEach { item( icon = { Icon( it.icon, contentDescription = stringResource(it.contentDescription) ) }, label = { Text(stringResource(it.label)) }, selected = it == currentDestination, onClick = { currentDestination = it }, colors = myNavigationSuiteItemColors, ) } }, ) { // Content... }
Dostosuj typy nawigacji
Domyślne zachowanie NavigationSuiteScaffold
zmienia interfejs nawigacji na podstawie klas rozmiaru okna. Możesz jednak zastąpić to działanie. Jeśli na przykład aplikacja wyświetla jeden duży panel treści w kanale, może używać stałej szuflady nawigacji po rozwiniętych oknach, ale może wrócić do domyślnego działania w przypadku klas kompaktowych i średnich:
val adaptiveInfo = currentWindowAdaptiveInfo() val customNavSuiteType = with(adaptiveInfo) { if (windowSizeClass.windowWidthSizeClass == WindowWidthSizeClass.EXPANDED) { NavigationSuiteType.NavigationDrawer } else { NavigationSuiteScaffoldDefaults.calculateFromAdaptiveInfo(adaptiveInfo) } } NavigationSuiteScaffold( navigationSuiteItems = { /* ... */ }, layoutType = customNavSuiteType, ) { // Content... }
Dodatkowe materiały
Zobacz wskazówki dotyczące stylu Material Design:
Zobacz te komponenty biblioteki androidx.compose.material3
: