`CoordinatorLayout`is a`ViewGroup`that enables complex, overlapping, and nested layouts. It's used as a container to enable specific Material Design interactions, such as expanding/collapsing toolbars and bottom sheets, for Views contained within it.

In Compose, the closest equivalent of a`CoordinatorLayout`is a[`Scaffold`](https://developer.android.com/develop/ui/compose/components/scaffold). A`Scaffold`provides content slots for combining Material Components into common screen patterns and interactions. This page describes how you can migrate your`CoordinatorLayout`implementation to use`Scaffold`in Compose.

## 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.

       <!--  <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" />

   | **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](https://developer.android.com/develop/ui/compose/migrate/strategy). However, if you are unable to do so, you can add an`AndroidView`to use Views within Compose. See[Using Views in Compose](https://developer.android.com/develop/ui/compose/migrate/interoperability-apis/views-in-compose)to learn more.
2. 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:

   <br />

   ```kotlin
   composeView.setContent {
       Scaffold(Modifier.fillMaxSize()) { contentPadding ->
           // Scaffold contents
           // ...
       }
   }https://github.com/android/snippets/blob/95aeebd507b29719a9e7d5a839f101bbbe42ea72/compose/snippets/src/main/java/com/example/compose/snippets/interop/MigrationCommonScenariosSnippets.kt#L263-L270
   ```

   <br />

3. 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`.

   <br />

   ```kotlin
   composeView.setContent {
       Scaffold(Modifier.fillMaxSize()) { contentPadding ->
           val pagerState = rememberPagerState {
               10
           }
           HorizontalPager(
               state = pagerState,
               modifier = Modifier.padding(contentPadding)
           ) { /* Page contents */ }
       }
   }https://github.com/android/snippets/blob/95aeebd507b29719a9e7d5a839f101bbbe42ea72/compose/snippets/src/main/java/com/example/compose/snippets/interop/MigrationCommonScenariosSnippets.kt#L276-L286
   ```

   <br />

4. 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`](https://developer.android.com/reference/kotlin/androidx/compose/material3/package-summary#TopAppBar(kotlin.Function0,androidx.compose.ui.Modifier,kotlin.Function0,kotlin.Function1,androidx.compose.foundation.layout.WindowInsets,androidx.compose.material3.TopAppBarColors,androidx.compose.material3.TopAppBarScrollBehavior)), and the`floatingActionButton`slot to provide a[`FloatingActionButton`](https://developer.android.com/reference/kotlin/androidx/compose/material3/package-summary#FloatingActionButton(kotlin.Function0,androidx.compose.ui.Modifier,androidx.compose.ui.graphics.Shape,androidx.compose.ui.graphics.Color,androidx.compose.ui.graphics.Color,androidx.compose.material3.FloatingActionButtonElevation,androidx.compose.foundation.interaction.MutableInteractionSource,kotlin.Function0)).

   <br />

   ```kotlin
   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 */ }
       }
   }https://github.com/android/snippets/blob/95aeebd507b29719a9e7d5a839f101bbbe42ea72/compose/snippets/src/main/java/com/example/compose/snippets/interop/MigrationCommonScenariosSnippets.kt#L293-L322
   ```

   <br />

## Common use cases

### Collapse and expand toolbars

In the View system, to collapse and expand the toolbar with`CoordinatorLayout`, you use an`AppBarLayout`as a container for the toolbar. You can then specify a[`Behavior`](https://developer.android.com/reference/androidx/coordinatorlayout/widget/CoordinatorLayout.Behavior)through`layout_behavior`in XML on the associated scrollable View (like`RecyclerView`or`NestedScrollView`) to declare how the toolbar collapses/expands as you scroll.

In Compose, you can achieve a similar effect through a[`TopAppBarScrollBehavior`](https://developer.android.com/reference/kotlin/androidx/compose/material3/TopAppBarScrollBehavior). For example, to implement a collapsing/expanding toolbar so that the toolbar appears when you scroll up, follow these steps:

1. Call`TopAppBarDefaults.enterAlwaysScrollBehavior()`to create a`TopAppBarScrollBehavior`.
2. Provide the created`TopAppBarScrollBehavior`to the`TopAppBar`.
3. Connect the[`NestedScrollConnection`](https://developer.android.com/reference/kotlin/androidx/compose/material3/TopAppBarScrollBehavior#nestedScrollConnection())via`Modifier.nestedScroll`on the`Scaffold`so that the Scaffold can receive nested scroll events as the scrollable content scrolls up/down. This way, the contained app bar can appropriately collapse/expand as the content scrolls.

   <br />

   ```kotlin
   // 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 */
       // ...
   }https://github.com/android/snippets/blob/95aeebd507b29719a9e7d5a839f101bbbe42ea72/compose/snippets/src/main/java/com/example/compose/snippets/interop/MigrationCommonScenariosSnippets.kt#L330-L352
   ```

   <br />

| **Note:** If you are using Material 2 components, you must manually implement the collapsing/expanding toolbar yourself. Alternatively, you can use a`CoordinatorLayout`as the outer layout to your`ComposeView`. This method is documented in the[Migrating Sunflower to Jetpack Compose](https://medium.com/androiddevelopers/migrating-sunflower-to-jetpack-compose-f840fa3b9985)blog post.

#### Customize the collapsing/expanding scroll effect

You can provide several parameters for[`enterAlwaysScrollBehavior`](https://developer.android.com/reference/kotlin/androidx/compose/material3/TopAppBarDefaults#enterAlwaysScrollBehavior(androidx.compose.material3.TopAppBarState,kotlin.Function0,androidx.compose.animation.core.AnimationSpec,androidx.compose.animation.core.DecayAnimationSpec))to customize the collapsing/expanding animation effect.`TopAppBarDefaults`also provides other`TopAppBarScrollBehavior`such as[`exitUntilCollapsedScrollBehavior`](https://developer.android.com/reference/kotlin/androidx/compose/material3/TopAppBarDefaults#exitUntilCollapsedScrollBehavior(androidx.compose.material3.TopAppBarState,kotlin.Function0,androidx.compose.animation.core.AnimationSpec,androidx.compose.animation.core.DecayAnimationSpec)), which only expands the app bar when the content is scrolled all the way down.

To create a completely custom effect (for example, a parallax effect), you can also create your own`NestedScrollConnection`and offset the toolbar manually as the content scrolls. See the[Nested scroll sample](https://cs.android.com/androidx/platform/frameworks/support/+/androidx-main:compose/ui/ui/samples/src/main/java/androidx/compose/ui/samples/NestedScrollSamples.kt;l=53?q=NestedScrollConnectionSample)on AOSP for a code example.

### Drawers

With Views, you implement a[navigation drawer](https://m3.material.io/components/navigation-drawer/overview)by using a[`DrawerLayout`](https://developer.android.com/reference/androidx/drawerlayout/widget/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`](https://developer.android.com/reference/com/google/android/material/navigation/NavigationView), to display the navigation options in the drawer.

In Compose, you can implement a navigation drawer using the[`ModalNavigationDrawer`](https://developer.android.com/reference/kotlin/androidx/compose/material3/package-summary#ModalNavigationDrawer(kotlin.Function0,androidx.compose.ui.Modifier,androidx.compose.material3.DrawerState,kotlin.Boolean,androidx.compose.ui.graphics.Color,kotlin.Function0))composable.`ModalNavigationDrawer`offers a`drawerContent`slot for the drawer and a`content`slot for the screen's content.

<br />

```kotlin
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
        // ...
    }
}https://github.com/android/snippets/blob/95aeebd507b29719a9e7d5a839f101bbbe42ea72/compose/snippets/src/main/java/com/example/compose/snippets/interop/MigrationCommonScenariosSnippets.kt#L359-L379
```

<br />

See[Drawers](https://developers.android.com/develop/ui/compose/layouts/material#drawers)to learn more.

### Snackbars

`Scaffold`provides a`snackbarHost`slot, which can accept a`SnackbarHost`composable to display a`Snackbar`.

<br />

```kotlin
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
    // ...
}https://github.com/android/snippets/blob/95aeebd507b29719a9e7d5a839f101bbbe42ea72/compose/snippets/src/main/java/com/example/compose/snippets/interop/MigrationCommonScenariosSnippets.kt#L386-L408
```

<br />

See[Snackbars](https://developers.android.com/develop/ui/compose/layouts/material#snackbar)to learn more.

## Learn more

For more information about migrating a`CoordinatorLayout`to Compose, see the following resources:

- [Material Components and layouts](https://developer.android.com/develop/ui/compose/layouts/material): Documentation on Material Design components that are supported in Compose, like`Scaffold`.
- [Migrating Sunflower to Jetpack Compose](https://medium.com/androiddevelopers/migrating-sunflower-to-jetpack-compose-f840fa3b9985): A blog post that documents the migration journey from Views to Compose of the Sunflower sample app, which contains a`CoordinatorLayout`.

## Recommended for you

- Note: link text is displayed when JavaScript is off
- [Material Components and layouts](https://developer.android.com/develop/ui/compose/layouts/material)
- [Window insets in Compose](https://developer.android.com/develop/ui/compose/layouts/insets)
- [Scroll](https://developer.android.com/develop/ui/compose/touch-input/pointer-input/scroll)