O layout do painel de suporte mantém o foco do usuário no conteúdo principal do app, mostrando informações de suporte relevantes. Por exemplo, o painel principal pode mostrar detalhes sobre um filme, enquanto o painel de suporte lista filmes semelhantes, filmes do mesmo diretor ou obras com os mesmos atores.
Para mais detalhes, consulte as diretrizes do painel de suporte do Material 3.
Implementar um painel de suporte com um scaffold
NavigableSupportingPaneScaffold é um elemento combinável que simplifica a implementação de um layout de painel de suporte no Jetpack Compose. Ele envolve
SupportingPaneScaffold e adiciona navegação integrada e processamento de volta preditivo
Um scaffold de painel de suporte aceita até três painéis:
- Painel principal: mostra o conteúdo principal.
- Painel de suporte: fornece contexto ou ferramentas adicionais relacionados ao painel principal.
- Painel extra (opcional): usado para conteúdo complementar quando necessário.
O scaffold se adapta com base no tamanho da janela:
- Em janelas grandes, os painéis principal e de suporte aparecem lado a lado.
Em janelas pequenas, apenas um painel fica visível por vez, alternando à medida que os usuários navegam.
Figura 1. Layout do painel de suporte.
Adicionar dependências
NavigableSupportingPaneScaffold faz parte da biblioteca de layout adaptável do Material 3.
Adicione as três dependências relacionadas a seguir ao arquivo build.gradle do app ou módulo:
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'
adaptável: elementos básicos de baixo nível, como
HingeInfoePostureadaptive-layout: layouts adaptáveis, como
ListDetailPaneScaffoldeSupportingPaneScaffoldadaptive-navigation: elementos combináveis para navegar dentro e entre painéis, bem como layouts adaptáveis que oferecem suporte à navegação por padrão, como
NavigableListDetailPaneScaffoldeNavigableSupportingPaneScaffold
Verifique se o projeto inclui a versão 1.1.0-beta1 ou mais recente do compose-material3-adaptive.
Ativar o gesto de volta preditivo
Para ativar animações de volta preditivas no Android 15 ou versões anteriores, é necessário ativar o suporte ao gesto de volta preditivo. Para ativar, adicione
android:enableOnBackInvokedCallback="true" à tag <application> ou
às tags <activity> individuais no arquivo AndroidManifest.xml.
Quando o app é destinado ao Android 16 (nível 36 da API) ou versões mais recentes, a volta preditiva é ativada por padrão.
Criar um navegador
Em janelas pequenas, apenas um painel é mostrado por vez. Portanto, use um
ThreePaneScaffoldNavigator para ir e voltar dos painéis. Crie uma instância
do navegador com rememberSupportingPaneScaffoldNavigator.
val scaffoldNavigator = rememberSupportingPaneScaffoldNavigator() val scope = rememberCoroutineScope()
Transmitir o navegador para o scaffold
O scaffold exige um ThreePaneScaffoldNavigator, que é uma interface
que representa o estado do scaffold, o ThreePaneScaffoldValue e uma
PaneScaffoldDirective.
NavigableSupportingPaneScaffold( navigator = scaffoldNavigator, mainPane = { /*...*/ }, supportingPane = { /*...*/ }, )
Os painéis principal e de suporte são elementos combináveis que contêm seu conteúdo. Use
AnimatedPane para aplicar as animações de painel padrão durante a navegação. Use
o valor do scaffold para verificar se o painel de suporte está oculto. Se estiver,
mostre um botão que chama
navigateTo(SupportingPaneScaffoldRole.Supporting) para mostrar o
painel de suporte.
Para telas grandes, use o ThreePaneScaffoldNavigator.navigateBack()
método para dispensar o painel de suporte, transmitindo a
BackNavigationBehavior.PopUntilScaffoldValueChange constante. Chamar este
método força uma recomposição do NavigableSupportingPaneScaffold.
Durante a recomposição, verifique a
ThreePaneScaffoldNavigator.currentDestination propriedade para determinar
se o painel de suporte será mostrado.
Confira uma implementação completa do scaffold:
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") } } } )
Extrair elementos combináveis do painel
Extraia os painéis individuais de um SupportingPaneScaffold em seus próprios elementos combináveis para torná-los reutilizáveis e testáveis. Use ThreePaneScaffoldScope
para acessar AnimatedPane se quiser as animações padrão:
@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") } } }
A extração dos painéis em elementos combináveis simplifica o uso do SupportingPaneScaffold (compare o seguinte com a implementação completa do scaffold na seção anterior):
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) }, )
Se você precisar de mais controle sobre aspectos específicos do scaffold, use
SupportingPaneScaffold em vez de NavigableSupportingPaneScaffold. Isso
aceita um PaneScaffoldDirective e ThreePaneScaffoldValue ou
ThreePaneScaffoldState separadamente. Essa flexibilidade permite implementar uma lógica personalizada para o espaçamento do painel e determinar quantos painéis serão mostrados simultaneamente. Também é possível ativar o suporte de volta preditivo adicionando ThreePaneScaffoldPredictiveBackHandler.
Adicionar ThreePaneScaffoldPredictiveBackHandler
Anexe o gerenciador de volta preditivo que usa uma instância do navegador de scaffold e especifique o backBehavior. Isso determina como os destinos são retirados da backstack durante a navegação de retorno. Em seguida, transmita o scaffoldDirective e o scaffoldState para SupportingPaneScaffold. Use a sobrecarga que aceita um ThreePaneScaffoldState, transmitindo scaffoldNavigator.scaffoldState.
Defina os painéis principal e de suporte em SupportingPaneScaffold. Use AnimatedPane para animações de painel padrão.
Depois de implementar essas etapas, o código vai ficar parecido com este:
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) }, )