A maioria dos apps tem alguns destinos de nível superior que podem ser acessados pela interface de navegação principal do app. Em janelas compactas, como a tela de um smartphone padrão, os destinos geralmente são mostrados em uma barra de navegação na parte de baixo da janela. Em uma janela expandida, como um app em tela cheia em um tablet, uma coluna de navegação ao lado do app geralmente é uma escolha melhor, já que os controles de navegação são mais fáceis de acessar enquanto você segura os lados esquerdo e direito do dispositivo.
NavigationSuiteScaffold
simplifica a alternância
entre interfaces de navegação mostrando o elemento combinável de interface de navegação apropriado
com base em WindowSizeClass
. Isso inclui mudar
dinamicamente a interface durante mudanças no tamanho da janela no tempo de execução. O comportamento padrão é
mostrar um dos seguintes componentes de interface:
- Barra de navegação se a largura ou altura for compacta ou se o dispositivo estiver na posição de mesa
- Coluna de navegação para tudo o mais
Adicionar dependências
NavigationSuiteScaffold
faz parte da biblioteca
pacote de navegação adaptativa do Material3. Adicione uma dependência para a biblioteca no arquivo build.gradle
do app
ou módulo:
Kotlin
implementation("androidx.compose.material3:material3-adaptive-navigation-suite")
Groovy
implementation 'androidx.compose.material3:material3-adaptive-navigation-suite'
Criar um esqueleto
As duas partes principais de NavigationSuiteScaffold
são os itens do pacote de navegação
e o conteúdo do destino selecionado. É possível definir diretamente os
itens da suíte de navegação em um elemento combinável, mas é comum que eles sejam definidos
em outro lugar, por exemplo, em um tipo enumerado:
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), }
Para usar NavigationSuiteScaffold
, você precisa rastrear o destino atual, o que
pode ser feito usando rememberSaveable
:
var currentDestination by rememberSaveable { mutableStateOf(AppDestinations.HOME) }
No exemplo abaixo, o parâmetro navigationSuiteItems
(tipo
NavigationSuiteScope
) usa a função item
para definir a interface de navegação de um destino individual. A interface de destino é
usada em barras de navegação, colunas e gavetas. Para criar itens de navegação, você
repete o AppDestinations
(definido no snippet anterior):
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. }
Na lambda de conteúdo de destino, use o valor currentDestination
para
decidir qual interface mostrar. Se você usa uma biblioteca de navegação no app, use-a
aqui para mostrar o destino adequado. Uma instrução WHEN pode ser suficiente:
NavigationSuiteScaffold( navigationSuiteItems = { /*...*/ } ) { // Destination content. when (currentDestination) { AppDestinations.HOME -> HomeDestination() AppDestinations.FAVORITES -> FavoritesDestination() AppDestinations.SHOPPING -> ShoppingDestination() AppDestinations.PROFILE -> ProfileDestination() } }
Mudar de cor
NavigationSuiteScaffold
cria um Surface
sobre toda a área
que o scaffold ocupa, normalmente a janela inteira. Além disso, o esqueleto
desenha a interface de navegação específica, como um NavigationBar
.
A superfície e a interface de navegação usam os valores especificados no tema
do app, mas você pode substituir os valores do tema.
O parâmetro containerColor
especifica a cor da superfície. O padrão
é a cor de plano de fundo do esquema de cores. O parâmetro contentColor
especifica a cor do conteúdo na superfície. O padrão é a cor "ativada"
do que for especificado para containerColor
. Por exemplo, se containerColor
usar a cor background
, contentColor
usará a cor onBackground
.
Consulte Aplicação de temas do Material Design 3 no Compose
para mais detalhes sobre como o sistema de cores funciona. Ao substituir esses valores,
use os valores definidos no tema para que o app ofereça suporte aos modos de exibição
claro e escuro:
NavigationSuiteScaffold( navigationSuiteItems = { /* ... */ }, containerColor = MaterialTheme.colorScheme.primary, contentColor = MaterialTheme.colorScheme.onPrimary, ) { // Content... }
A interface de navegação é exibida na frente da superfície NavigationSuiteScaffold
.
Os valores padrão para as cores da interface são fornecidos por
NavigationSuiteDefaults.colors()
, mas você
também pode substituir esses valores. Por exemplo, se você quiser que o plano de fundo
da barra de navegação seja transparente, mas que os outros valores sejam os padrões,
substitua navigationBarContainerColor
:
NavigationSuiteScaffold( navigationSuiteItems = { /* ... */ }, navigationSuiteColors = NavigationSuiteDefaults.colors( navigationBarContainerColor = Color.Transparent, ) ) { // Content... }
Você pode personalizar cada item na IU de navegação. Ao chamar a função
item
, é possível transmitir uma instância de
NavigationSuiteItemColors
. A classe especifica
as cores dos itens em uma barra de navegação, uma coluna de navegação e uma
gaveta de navegação. Isso significa que você pode ter cores idênticas em cada tipo de interface de navegação
ou variar as cores com base nas suas necessidades. Defina as cores no
nível NavigationSuiteScaffold
para usar a mesma instância de objeto para todos os itens
e chame a função NavigationSuiteDefaults.itemColors()
para substituir apenas
aqueles que você quer mudar:
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... }
Personalizar tipos de navegação
O comportamento padrão de NavigationSuiteScaffold
muda a interface de navegação
com base nas classes de tamanho
de janela. No entanto, talvez você queira modificar esse comportamento. Por exemplo, se o app mostra um único
painel grande de conteúdo para um feed, ele pode usar uma gaveta de navegação
permanente para janelas expandidas, mas ainda retornar ao comportamento padrão para
classes de tamanho de janela compactas e médias:
val adaptiveInfo = currentWindowAdaptiveInfo() val customNavSuiteType = with(adaptiveInfo) { if (windowSizeClass.windowWidthSizeClass == WindowWidthSizeClass.EXPANDED) { NavigationSuiteType.NavigationDrawer } else { NavigationSuiteScaffoldDefaults.calculateFromAdaptiveInfo(adaptiveInfo) } } NavigationSuiteScaffold( navigationSuiteItems = { /* ... */ }, layoutType = customNavSuiteType, ) { // Content... }
Outros recursos
Orientações do Material Design:
Componentes da biblioteca
androidx.compose.material3
: