CordinatorLayout

CordinatorLayout

Migration steps

To migrate CoordinatorLayout to Scaffold, follow these steps:
  1. In the snippet below, the CoordinatorLayout contains an AppBarLayout for containing a ToolBar, a ViewPager, and a FloatingActionButton. Comment out the CoordinatorLayout and its children from your UI hierarchy and add a ComposeView to replace it.
👉
Note: Since CoordinatorLayout is a ViewGroup, it's best to migrate all its child views to Compose at the same time or prior to this step, depending on your migration strategy. However, if you are unable to do so, you can add an AndroidView to use Views within Compose. See Using Views in Compose to learn more.
 
  1. In your Fragment or Activity, obtain a reference to the ComposeView you just added and call the setContent method on it. In the body of the method, set a Scaffold as its content:
composeView.setContent { Scaffold(Modifier.fillMaxSize()) { contentPadding -> // Scaffold contents // ... } }
 
  1. In the content of your Scaffold, add your screen's primary content within it. Because the primary content in the XML above is a ViewPager2, we'll use a HorizontalPager, which is the Compose equivalent of it. The content lambda of the Scaffold also receives an instance of PaddingValues that should be applied to the content root. You can use Modifier.padding to apply the same PaddingValues to the HorizontalPager.
composeView.setContent { Scaffold(Modifier.fillMaxSize()) { contentPadding -> val pagerState = rememberPagerState { 10 } HorizontalPager( state = pagerState, modifier = Modifier.padding(contentPadding) ) { /* Page contents */ } } }
 
  1. Use other content slots that Scaffold provides to add more screen elements and migrate remaining child Views. You can use the topBar slot to add a TopAppBar, and the floatingActionButton slot to provide a FloatingActionButton.
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 */ } } }

Drawers

With Views, you implement a navigation drawer by using a DrawerLayout as the root view. In turn, your CoordinatorLayout is a child view of the DrawerLayout. The DrawerLayout also contains another child view, such as a NavigationView, to display the navigation options in the drawer.
In Compose, you can implement a navigation drawer using the ModalNavigationDrawer composable. ModalNavigationDrawer offers a drawerContent slot for the drawer and a content slot for the screen's content.
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 // ... } }

Snackbars

Scaffold provides a snackbarHost slot, which can accept a SnackbarHost composable to display a 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 // ... }MigrationCommonScenariosSnippets.kt