{% setvar book_path %}/reference/androidx/_book.yaml{% endsetvar %} {% include "_shared/_reference-head-tags.html" %}

ModalBottomSheetKt

public final class ModalBottomSheetKt


Summary

Public methods

static final void
@Composable
@ExperimentalMaterial3Api
ModalBottomSheet(
    @NonNull Function0<Unit> onDismissRequest,
    @NonNull Modifier modifier,
    @NonNull SheetState sheetState,
    @NonNull Dp sheetMaxWidth,
    @NonNull Shape shape,
    @NonNull Color containerColor,
    @NonNull Color contentColor,
    @NonNull Dp tonalElevation,
    @NonNull Color scrimColor,
    @Composable Function0<Unit> dragHandle,
    @NonNull WindowInsets windowInsets,
    @NonNull ModalBottomSheetProperties properties,
    @Composable @ExtensionFunctionType @NonNull Function1<@NonNull ColumnScopeUnit> content
)

Material Design modal bottom sheet.

static final @NonNull SheetState
@Composable
@ExperimentalMaterial3Api
rememberModalBottomSheetState(
    boolean skipPartiallyExpanded,
    @NonNull Function1<@NonNull SheetValue, @NonNull Boolean> confirmValueChange
)

Create and remember a SheetState for ModalBottomSheet.

Public methods

ModalBottomSheet

@Composable
@ExperimentalMaterial3Api
public static final void ModalBottomSheet(
    @NonNull Function0<Unit> onDismissRequest,
    @NonNull Modifier modifier,
    @NonNull SheetState sheetState,
    @NonNull Dp sheetMaxWidth,
    @NonNull Shape shape,
    @NonNull Color containerColor,
    @NonNull Color contentColor,
    @NonNull Dp tonalElevation,
    @NonNull Color scrimColor,
    @Composable Function0<Unit> dragHandle,
    @NonNull WindowInsets windowInsets,
    @NonNull ModalBottomSheetProperties properties,
    @Composable @ExtensionFunctionType @NonNull Function1<@NonNull ColumnScopeUnit> content
)

Material Design modal bottom sheet.

Modal bottom sheets are used as an alternative to inline menus or simple dialogs on mobile, especially when offering a long list of action items, or when items require longer descriptions and icons. Like dialogs, modal bottom sheets appear in front of app content, disabling all other app functionality when they appear, and remaining on screen until confirmed, dismissed, or a required action has been taken.

Bottom sheet image

A simple example of a modal bottom sheet looks like this:

import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.WindowInsets
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.selection.toggleable
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Favorite
import androidx.compose.material3.BottomSheetDefaults
import androidx.compose.material3.Button
import androidx.compose.material3.Checkbox
import androidx.compose.material3.Icon
import androidx.compose.material3.ListItem
import androidx.compose.material3.ModalBottomSheet
import androidx.compose.material3.OutlinedTextField
import androidx.compose.material3.Text
import androidx.compose.material3.rememberModalBottomSheetState
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.semantics.Role
import androidx.compose.ui.unit.dp

var openBottomSheet by rememberSaveable { mutableStateOf(false) }
var skipPartiallyExpanded by remember { mutableStateOf(false) }
var edgeToEdgeEnabled by remember { mutableStateOf(false) }
val scope = rememberCoroutineScope()
val bottomSheetState = rememberModalBottomSheetState(
    skipPartiallyExpanded = skipPartiallyExpanded
)

// App content
Column(
    horizontalAlignment = Alignment.Start,
    verticalArrangement = Arrangement.spacedBy(4.dp)
) {
    Row(
        Modifier.toggleable(
            value = skipPartiallyExpanded,
            role = Role.Checkbox,
            onValueChange = { checked -> skipPartiallyExpanded = checked }
        )
    ) {
        Checkbox(checked = skipPartiallyExpanded, onCheckedChange = null)
        Spacer(Modifier.width(16.dp))
        Text("Skip partially expanded State")
    }
    Row(
        Modifier.toggleable(
            value = edgeToEdgeEnabled,
            role = Role.Checkbox,
            onValueChange = { checked -> edgeToEdgeEnabled = checked }
        )
    ) {
        Checkbox(checked = edgeToEdgeEnabled, onCheckedChange = null)
        Spacer(Modifier.width(16.dp))
        Text("Toggle edge to edge enabled")
    }
    Button(
        onClick = { openBottomSheet = !openBottomSheet },
        modifier = Modifier.align(Alignment.CenterHorizontally)
    ) {
        Text(text = "Show Bottom Sheet")
    }
}

// Sheet content
if (openBottomSheet) {
    val windowInsets = if (edgeToEdgeEnabled)
        WindowInsets(0) else BottomSheetDefaults.windowInsets

    ModalBottomSheet(
        onDismissRequest = { openBottomSheet = false },
        sheetState = bottomSheetState,
        windowInsets = windowInsets
    ) {

        Row(Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.Center) {
            Button(
                // Note: If you provide logic outside of onDismissRequest to remove the sheet,
                // you must additionally handle intended state cleanup, if any.
                onClick = {
                    scope.launch { bottomSheetState.hide() }.invokeOnCompletion {
                        if (!bottomSheetState.isVisible) {
                            openBottomSheet = false
                        }
                    }
                }
            ) {
                Text("Hide Bottom Sheet")
            }
        }
        var text by remember { mutableStateOf("") }
        OutlinedTextField(
            value = text,
            onValueChange = { text = it },
            modifier = Modifier.padding(horizontal = 16.dp),
            label = { Text("Text field") }
        )
        LazyColumn {
            items(25) {
                ListItem(
                    headlineContent = { Text("Item $it") },
                    leadingContent = {
                        Icon(
                            Icons.Default.Favorite,
                            contentDescription = "Localized description"
                        )
                    }
                )
            }
        }
    }
}
Parameters
@NonNull Function0<Unit> onDismissRequest

Executes when the user clicks outside of the bottom sheet, after sheet animates to Hidden.

@NonNull Modifier modifier

Optional Modifier for the bottom sheet.

@NonNull SheetState sheetState

The state of the bottom sheet.

@NonNull Dp sheetMaxWidth

Dp that defines what the maximum width the sheet will take. Pass in Dp.Unspecified for a sheet that spans the entire screen width.

@NonNull Shape shape

The shape of the bottom sheet.

@NonNull Color containerColor

The color used for the background of this bottom sheet

@NonNull Color contentColor

The preferred color for content inside this bottom sheet. Defaults to either the matching content color for containerColor, or to the current LocalContentColor if containerColor is not a color from the theme.

@NonNull Dp tonalElevation

The tonal elevation of this bottom sheet.

@NonNull Color scrimColor

Color of the scrim that obscures content when the bottom sheet is open.

@Composable Function0<Unit> dragHandle

Optional visual marker to swipe the bottom sheet.

@NonNull WindowInsets windowInsets

window insets to be passed to the bottom sheet window via PaddingValues params.

@NonNull ModalBottomSheetProperties properties

ModalBottomSheetProperties for further customization of this modal bottom sheet's behavior.

@Composable @ExtensionFunctionType @NonNull Function1<@NonNull ColumnScopeUnit> content

The content to be displayed inside the bottom sheet.

rememberModalBottomSheetState

@Composable
@ExperimentalMaterial3Api
public static final @NonNull SheetState rememberModalBottomSheetState(
    boolean skipPartiallyExpanded,
    @NonNull Function1<@NonNull SheetValue, @NonNull Boolean> confirmValueChange
)

Create and remember a SheetState for ModalBottomSheet.

Parameters
boolean skipPartiallyExpanded

Whether the partially expanded state, if the sheet is tall enough, should be skipped. If true, the sheet will always expand to the Expanded state and move to the Hidden state when hiding the sheet, either programmatically or by user interaction.

@NonNull Function1<@NonNull SheetValue, @NonNull Boolean> confirmValueChange

Optional callback invoked to confirm or veto a pending state change.