CoordinatorLayout é um ViewGroup que permite layouts complexos, sobrepostos e
aninhados. Ele é usado como um contêiner para ativar interações específicas do Material Design, como barras de ferramentas e painéis inferiores expansíveis/recolhíveis, para Views contidos nele.
No Compose, o equivalente mais próximo de um CoordinatorLayout é um
Scaffold. Um Scaffold oferece slots de conteúdo para combinar componentes do Material
em padrões e interações de tela comuns. Nesta página, descrevemos como migrar sua implementação do CoordinatorLayout para usar o Scaffold no Compose.
Etapas da migração
Para migrar CoordinatorLayout para Scaffold, siga estas etapas:
No snippet abaixo, o
CoordinatorLayoutcontém umAppBarLayoutpara conter umToolBar, umViewPagere umFloatingActionButton. Comente oCoordinatorLayoute os filhos dele na hierarquia da interface e adicione umComposeViewpara substituir.<!-- <androidx.coordinatorlayout.widget.CoordinatorLayout--> <!-- android:id="@+id/coordinator_layout"--> <!-- android:layout_width="match_parent"--> <!-- android:layout_height="match_parent"--> <!-- android:fitsSystemWindows="true">--> <!-- <androidx.compose.ui.platform.ComposeView--> <!-- android:id="@+id/compose_view"--> <!-- android:layout_width="match_parent"--> <!-- android:layout_height="match_parent"--> <!-- app:layout_behavior="@string/appbar_scrolling_view_behavior" />--> <!-- <com.google.android.material.appbar.AppBarLayout--> <!-- android:id="@+id/app_bar_layout"--> <!-- android:layout_width="match_parent"--> <!-- android:layout_height="wrap_content"--> <!-- android:fitsSystemWindows="true"--> <!-- android:theme="@style/Theme.Sunflower.AppBarOverlay">--> <!-- AppBarLayout contents here --> <!-- </com.google.android.material.appbar.AppBarLayout>--> <!-- </androidx.coordinatorlayout.widget.CoordinatorLayout>--> <androidx.compose.ui.platform.ComposeView android:id="@+id/compose_view" android:layout_width="match_parent" android:layout_height="match_parent" />No seu fragmento ou atividade, receba uma referência ao
ComposeViewque você acabou de adicionar e chame o métodosetContentnele. No corpo do método, defina umScaffoldcomo conteúdo:composeView.setContent { Scaffold(Modifier.fillMaxSize()) { contentPadding -> // Scaffold contents // ... } }
No conteúdo do seu
Scaffold, adicione o conteúdo principal da tela. Como o conteúdo principal no XML acima é umViewPager2, vamos usar umHorizontalPager, que é o equivalente do Compose. A lambdacontentdoScaffoldtambém recebe uma instância dePaddingValuesque precisa ser aplicada à raiz do conteúdo. Você pode usarModifier.paddingpara aplicar o mesmoPaddingValuesaoHorizontalPager.composeView.setContent { Scaffold(Modifier.fillMaxSize()) { contentPadding -> val pagerState = rememberPagerState { 10 } HorizontalPager( state = pagerState, modifier = Modifier.padding(contentPadding) ) { /* Page contents */ } } }
Use outros slots de conteúdo fornecidos pelo
Scaffoldpara adicionar mais elementos de tela e migrar as Views filhas restantes. É possível usar o slottopBarpara adicionar umTopAppBare o slotfloatingActionButtonpara fornecer umFloatingActionButton.composeView.setContent { Scaffold( Modifier.fillMaxSize(), topBar = { TopAppBar( title = { Text("My App") } ) }, floatingActionButton = { FloatingActionButton( onClick = { /* Handle click */ } ) { Icon( Icons.Filled.Add, contentDescription = "Add Button" ) } } ) { contentPadding -> val pagerState = rememberPagerState { 10 } HorizontalPager( state = pagerState, modifier = Modifier.padding(contentPadding) ) { /* Page contents */ } } }
Casos de uso comuns
Recolher e expandir barras de ferramentas
No sistema de visualização, para recolher e expandir a barra de ferramentas com CoordinatorLayout,
use um AppBarLayout como contêiner da barra de ferramentas. Em seguida, especifique um
Behavior usando layout_behavior em XML na visualização rolável associada (como RecyclerView ou NestedScrollView) para declarar como a barra de ferramentas
vai recolher/expandir conforme você rola a tela.
No Compose, é possível conseguir um efeito semelhante usando um
TopAppBarScrollBehavior. Por exemplo, para implementar uma barra de ferramentas
que se recolhe/expande para aparecer quando você rola para cima, siga estas etapas:
- Chame
TopAppBarDefaults.enterAlwaysScrollBehavior()para criar umTopAppBarScrollBehavior. - Forneça o
TopAppBarScrollBehaviorcriado aoTopAppBar. Conecte o
NestedScrollConnectionviaModifier.nestedScrollnoScaffoldpara que o Scaffold possa receber eventos de rolagem aninhada à medida que o conteúdo rolável é movido para cima/para baixo. Assim, a barra de apps contida pode ser recolhida/expandida adequadamente conforme o conteúdo rola.// 1. Create the TopAppBarScrollBehavior val scrollBehavior = TopAppBarDefaults.enterAlwaysScrollBehavior() Scaffold( topBar = { TopAppBar( title = { Text("My App") }, // 2. Provide scrollBehavior to TopAppBar scrollBehavior = scrollBehavior ) }, // 3. Connect the scrollBehavior.nestedScrollConnection to the Scaffold modifier = Modifier .fillMaxSize() .nestedScroll(scrollBehavior.nestedScrollConnection) ) { contentPadding -> /* Contents */ // ... }
Personalizar o efeito de rolagem de recolhimento/expansão
É possível fornecer vários parâmetros para enterAlwaysScrollBehavior e personalizar o efeito de animação de recolhimento/expansão. O TopAppBarDefaults também
oferece outros TopAppBarScrollBehavior, como
exitUntilCollapsedScrollBehavior, que só expande a barra de apps quando
o conteúdo é rolado até o final.
Para criar um efeito totalmente personalizado (por exemplo, um efeito de paralaxe), você também pode criar seu próprio NestedScrollConnection e compensar a barra de ferramentas manualmente à medida que o conteúdo rola. Consulte o exemplo de rolagem aninhada no AOSP para ver um exemplo de código.
Gavetas
Com o Views, você implementa uma gaveta de navegação usando um
DrawerLayout como a visualização raiz. Por sua vez, seu CoordinatorLayout é uma visualização filha do DrawerLayout. O DrawerLayout também contém outra visualização filha, como um NavigationView, para mostrar as opções de navegação na gaveta.
No Compose, é possível implementar uma gaveta de navegação usando o
elemento combinável ModalNavigationDrawer. O ModalNavigationDrawer oferece um
slot drawerContent para a gaveta e um slot content para o conteúdo
da tela.
ModalNavigationDrawer( drawerContent = { ModalDrawerSheet { Text("Drawer title", modifier = Modifier.padding(16.dp)) HorizontalDivider() NavigationDrawerItem( label = { Text(text = "Drawer Item") }, selected = false, onClick = { /*TODO*/ } ) // ...other drawer items } } ) { Scaffold(Modifier.fillMaxSize()) { contentPadding -> // Scaffold content // ... } }
Consulte Gavetas para saber mais.
Snackbars
O Scaffold oferece um slot snackbarHost, que pode aceitar um elemento combinável SnackbarHost
para mostrar um Snackbar.
val scope = rememberCoroutineScope() val snackbarHostState = remember { SnackbarHostState() } Scaffold( snackbarHost = { SnackbarHost(hostState = snackbarHostState) }, floatingActionButton = { ExtendedFloatingActionButton( text = { Text("Show snackbar") }, icon = { Icon(Icons.Filled.Image, contentDescription = "") }, onClick = { scope.launch { snackbarHostState.showSnackbar("Snackbar") } } ) } ) { contentPadding -> // Screen content // ... }
Consulte Snackbars para saber mais.
Saiba mais
Para mais informações sobre como migrar um CoordinatorLayout para o Compose, consulte os
recursos a seguir:
- Componentes e layouts do Material Design: documentação sobre componentes do Material Design
compatíveis com o Compose, como
Scaffold. - Migração do Sunflower para o Jetpack Compose: uma postagem no blog que
documenta a jornada de migração de Views para Compose do app de exemplo
Sunflower, que contém um
CoordinatorLayout.
Recomendados para você
- Observação: o texto do link aparece quando o JavaScript está desativado.
- Componentes e layouts do Material Design
- Encartes de janela no Compose
- Rolagem