CoordinatorLayout es un ViewGroup que permite diseños complejos, superpuestos y anidados. Se usa como contenedor para habilitar interacciones específicas de Material Design, como la expansión o contracción de barras de herramientas y hojas inferiores, para las vistas que contiene.
En Compose, el equivalente más cercano de un CoordinatorLayout es un
Scaffold. Un Scaffold proporciona ranuras de contenido para combinar componentes de Material en patrones e interacciones de pantalla comunes. En esta página, se describe cómo puedes migrar tu implementación de CoordinatorLayout para usar Scaffold en Compose.
Pasos de la migración
Para migrar CoordinatorLayout a Scaffold, sigue estos pasos:
En el siguiente fragmento, el
CoordinatorLayoutcontiene unAppBarLayoutpara contener unToolBar, unViewPagery unFloatingActionButton. Comenta elCoordinatorLayouty sus elementos secundarios de tu jerarquía de IU y agrega unComposeViewpara reemplazarlo.<!-- <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" />En tu fragmento o actividad, obtén una referencia al
ComposeViewque acabas de agregar y llama al métodosetContenten él. En el cuerpo del método, establece unScaffoldcomo su contenido:composeView.setContent { Scaffold(Modifier.fillMaxSize()) { contentPadding -> // Scaffold contents // ... } }
En el contenido de tu
Scaffold, agrega el contenido principal de la pantalla. Como el contenido principal en el XML anterior es unViewPager2, usaremos unHorizontalPager, que es el equivalente de Compose. La lambdacontentdelScaffoldtambién recibe una instancia dePaddingValuesque se debe aplicar a la raíz del contenido. Puedes usarModifier.paddingpara aplicar el mismoPaddingValuesalHorizontalPager.composeView.setContent { Scaffold(Modifier.fillMaxSize()) { contentPadding -> val pagerState = rememberPagerState { 10 } HorizontalPager( state = pagerState, modifier = Modifier.padding(contentPadding) ) { /* Page contents */ } } }
Usa otras ranuras de contenido que proporciona
Scaffoldpara agregar más elementos de pantalla y migrar las vistas secundarias restantes. Puedes usar la ranuratopBarpara agregar unTopAppBary la ranurafloatingActionButtonpara proporcionar unFloatingActionButton.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 habituales
Cómo contraer y expandir barras de herramientas
En el sistema de View, para contraer y expandir la barra de herramientas con CoordinatorLayout, usas un AppBarLayout como contenedor de la barra de herramientas. Luego, puedes especificar un
Behavior a través de layout_behavior en XML en la vista desplazable asociada (como RecyclerView o NestedScrollView) para declarar cómo se contrae o expande la barra de herramientas
mientras te desplazas.
En Compose, puedes lograr un efecto similar a través de un
TopAppBarScrollBehavior. Por ejemplo, para implementar una barra de herramientas que se contrae o expande de modo que aparezca cuando te desplazas hacia arriba, sigue estos pasos:
- Llama a
TopAppBarDefaults.enterAlwaysScrollBehavior()para crear unTopAppBarScrollBehavior. - Proporciona el
TopAppBarScrollBehaviorcreado alTopAppBar. Conecta el
NestedScrollConnectiona través deModifier.nestedScrollen elScaffoldpara que el Scaffold pueda recibir eventos de desplazamiento anidado a medida que el contenido desplazable se desplaza hacia arriba o hacia abajo. De esta manera, la barra de la app contenida puede contraerse o expandirse de manera adecuada a medida que se desplaza el contenido.// 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 */ // ... }
Personaliza el efecto de desplazamiento de contracción o expansión
Puedes proporcionar varios parámetros para enterAlwaysScrollBehavior para
personalizar el efecto de animación de contracción o expansión. TopAppBarDefaults también
proporciona otro TopAppBarScrollBehavior como
exitUntilCollapsedScrollBehavior, que solo expande la barra de la app cuando
el contenido se desplaza hasta el final.
Para crear un efecto completamente personalizado (por ejemplo, un efecto de paralaje), también puedes crear tu propio NestedScrollConnection y desplazar la barra de herramientas de forma manual a medida que se desplaza el contenido. Consulta la muestra de desplazamiento anidado en AOSP para ver un
ejemplo de código.
Paneles laterales
Con Views, implementas un panel lateral de navegación usando un
DrawerLayout como la vista raíz. A su vez, tu CoordinatorLayout es una vista secundaria del DrawerLayout. El DrawerLayout también contiene otra vista secundaria, como un NavigationView, para mostrar las opciones de navegación en el panel lateral.
En Compose, puedes implementar un panel lateral de navegación con el
ModalNavigationDrawer elemento componible. ModalNavigationDrawer ofrece una ranura drawerContent para el panel lateral y una ranura content para el contenido de la pantalla.
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 // ... } }
Consulta Paneles laterales para obtener más información.
Barras de notificaciones
Scaffold proporciona una ranura snackbarHost, que puede aceptar un elemento componible SnackbarHost
para mostrar un 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 // ... }
Consulta Barras de notificaciones para obtener más información.
Más información
Para obtener más información sobre cómo migrar un CoordinatorLayout a Compose, consulta los siguientes recursos:
- Componentes y diseños de Material: Documentación sobre los componentes de Material Design
compatibles con Compose, como
Scaffold. - Cómo migrar Sunflower a Jetpack Compose: Una entrada de blog que documenta el proceso de migración de Views a Compose de la app de ejemplo de Sunflower, que contiene un
CoordinatorLayout.
Recomendaciones para ti
- Nota: El texto del vínculo se muestra cuando JavaScript está desactivado
- Componentes y diseños de Material
- Inserciones de ventana en Compose
- Desplazamiento