O layout do painel de suporte mantém o foco do usuário no conteúdo principal do app enquanto mostra 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 o NavigableSupportingPaneScaffold
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 tratamento de volta preditiva.
Um esqueleto de painel de suporte oferece suporte a até três painéis:
- Painel principal: mostra o conteúdo principal.
- Painel de suporte: oferece mais contexto ou ferramentas relacionadas ao painel principal.
- Painel extra (opcional): usado para conteúdo complementar quando necessário.
O esqueleto se adapta com base no tamanho da janela:
- Em janelas grandes, os painéis principais e de suporte aparecem lado a lado.
Em janelas pequenas, apenas um painel fica visível por vez, alternando conforme 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 abaixo 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
HingeInfo
ePosture
layout-adaptável: layouts adaptáveis, como
ListDetailPaneScaffold
eSupportingPaneScaffold
.navegação-adaptável: elementos combináveis para navegar dentro e entre painéis, além de layouts adaptáveis que oferecem suporte à navegação por padrão, como
NavigableListDetailPaneScaffold
eNavigableSupportingPaneScaffold
.
Verifique se o projeto inclui a versão 1.1.0-beta1 do compose-material3-adaptive ou mais recente.
Ativar o gesto de volta preditivo
Para ativar as animações de volta preditiva no Android 15 ou versões anteriores, é necessário
ativar o gesto de volta preditivo. Para ativar, adicione
android:enableOnBackInvokedCallback="true"
à tag <application>
ou
<activity>
individuais no arquivo AndroidManifest.xml
.
Quando o app é direcionado 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 é exibido por vez. Use um
ThreePaneScaffoldNavigator
para alternar entre os painéis. Crie uma instância
do navegador com rememberSupportingPaneScaffoldNavigator
.
val scaffoldNavigator = rememberSupportingPaneScaffoldNavigator() val scope = rememberCoroutineScope()
Transmitir o navegador para o esqueleto
O esqueleto requer um ThreePaneScaffoldNavigator
, que é uma interface
que representa o estado do esqueleto, o ThreePaneScaffoldValue
e um
PaneScaffoldDirective
.
NavigableSupportingPaneScaffold( navigator = scaffoldNavigator, mainPane = { /*...*/ }, supportingPane = { /*...*/ }, )
O painel principal e o de suporte são elementos combináveis que contêm seu conteúdo. Use
AnimatedPane
para aplicar as animações padrão do painel durante a navegação. Use
o valor do scaffold para verificar se o painel de suporte está oculto.
Se estiver,
exiba um botão que chame
navigateTo(SupportingPaneScaffoldRole.Supporting)
para mostrar o
painel de suporte.
Confira uma implementação completa do esqueleto:
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") } } )
Extrair elementos combináveis do painel
Extraia os painéis individuais de um SupportingPaneScaffold
para os próprios
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( modifier: Modifier = Modifier, ) { AnimatedPane(modifier = modifier.safeContentPadding()) { // Supporting pane content Text("This is the supporting pane") } }
Extrair as panes em elementos combináveis simplifica o uso do
SupportingPaneScaffold
(compare o exemplo a seguir 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() }, )
Se você precisar de mais controle sobre aspectos específicos do scaffold, use
SupportingPaneScaffold
em vez de NavigableSupportingPaneScaffold
. Ele
aceita um PaneScaffoldDirective
e ThreePaneScaffoldValue
ou
ThreePaneScaffoldState
separadamente. Essa flexibilidade permite implementar
lógica personalizada para o espaçamento de painéis e determinar quantos painéis devem ser exibidos
simultaneamente. Também é possível ativar o suporte para volta preditiva adicionando
ThreePaneScaffoldPredictiveBackHandler
.
Adicionar ThreePaneScaffoldPredictiveBackHandler
Anexe o gerenciador de volta preditiva que usa uma instância de navegador de esqueleto e
especifique o backBehavior
. Isso determina como os destinos são retirados da
backstack durante a navegação de volta. Em seguida, transmita o scaffoldDirective
e
scaffoldState
para SupportingPaneScaffold
. Use a sobrecarga que aceita um
ThreePaneScaffoldState
, transmitindo scaffoldNavigator.scaffoldState
.
Defina os painéis principais e de suporte em SupportingPaneScaffold
. Use
AnimatedPane
para animações padrão do painel.
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() }, )