O layout do painel de suporte mantém o foco do usuário no conteúdo principal do app enquanto exibe 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 encapsula
SupportingPaneScaffold
e adiciona navegação integrada e processamento de
volta preditiva.
Um scaffold de painel de suporte pode ter 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 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 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 a seguir ao arquivo build.gradle
do seu
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'
adaptativa: elementos básicos de baixo nível, como
HingeInfo
ePosture
adaptive-layout: layouts adaptáveis, como
ListDetailPaneScaffold
eSupportingPaneScaffold
adaptive-navigation: 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 suporte ao gesto de volta preditiva. Para ativar, adicione
android:enableOnBackInvokedCallback="true"
à tag <application>
ou
às tags <activity>
individuais no arquivo AndroidManifest.xml
.
Quando o app for direcionado ao Android 16 (nível 36 da API) ou versões mais recentes, o retorno preditivo será ativado por padrão.
Criar um navegador
Em janelas pequenas, apenas um painel é exibido por vez. Use um
ThreePaneScaffoldNavigator
para navegar entre eles. Crie uma instância
do navegador com rememberSupportingPaneScaffoldNavigator
.
val scaffoldNavigator = rememberSupportingPaneScaffoldNavigator() val scope = rememberCoroutineScope()
Transmita o navegador ao scaffold
O scaffold exige um ThreePaneScaffoldNavigator
, que é uma interface
que representa o estado do scaffold, o ThreePaneScaffoldValue
e um
PaneScaffoldDirective
.
NavigableSupportingPaneScaffold( navigator = scaffoldNavigator, mainPane = { /*...*/ }, supportingPane = { /*...*/ }, )
O painel principal e o painel 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 exibir o painel de suporte.
Confira uma implementação completa do scaffold:
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
em elementos combináveis
próprios 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 os 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() }, )
Se você precisar de mais controle sobre aspectos específicos do scaffold, use
SupportingPaneScaffold
em vez de NavigableSupportingPaneScaffold
. Isso aceita um PaneScaffoldDirective
e um ThreePaneScaffoldValue
ou um ThreePaneScaffoldState
separadamente. Essa flexibilidade permite implementar
lógica personalizada para espaçamento de painéis e determinar quantos painéis devem ser mostrados
simultaneamente. Também é possível adicionar a volta preditiva incluindo
ThreePaneScaffoldPredictiveBackHandler
.
Adicionar ThreePaneScaffoldPredictiveBackHandler
Anexe o manipulador de volta preditiva 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 para trás. Em seguida, transmita scaffoldDirective
e
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, seu 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() }, )