Skip to main content

Implementing Bottom Sheet Dialog in Jetpack Compose

Bottom sheet dialogs are a popular UI component in modern Android apps, providing a flexible and intuitive way to present additional content without completely disrupting the user’s workflow. Jetpack Compose simplifies their implementation with its declarative UI approach, offering developers both simplicity and customization.

In this blog post, we will explore how to implement a bottom sheet dialog using Jetpack Compose. We'll cover both the basics and advanced customizations, ensuring you can create visually appealing and functional bottom sheets tailored to your app’s requirements.

Table of Contents

  1. Introduction to Bottom Sheet Dialogs

  2. Components of Bottom Sheet Dialog in Jetpack Compose

  3. Implementing a Simple Bottom Sheet

  4. Customizing the Bottom Sheet Dialog

  5. Handling State and Events

  6. Advanced Use Cases

  7. Best Practices and Performance Optimization

  8. Conclusion

1. Introduction to Bottom Sheet Dialogs

Bottom sheet dialogs can display additional content, actions, or menus that slide up from the bottom of the screen. There are two primary types:

  • Persistent Bottom Sheets: These remain visible and often contain core functionality (e.g., navigation).

  • Modal Bottom Sheets: These are temporary and used for user-specific actions or information.

Jetpack Compose provides tools to create both types with ease, leveraging ModalBottomSheetLayout and other composable functions.

2. Components of Bottom Sheet Dialog in Jetpack Compose

Before diving into code, let’s understand the core components:

  • ModalBottomSheetLayout: A composable that manages the modal bottom sheet’s state and layout.

  • SheetState: Used to control the visibility and behavior of the bottom sheet.

  • Coroutines: Often used to manage animations and sheet interactions asynchronously.

These elements combine to create a seamless bottom sheet dialog experience in Compose.

3. Implementing a Simple Bottom Sheet

Here’s how you can create a basic modal bottom sheet dialog:

Step 1: Add Dependencies

Ensure you have the latest Jetpack Compose library in your build.gradle:

implementation "androidx.compose.material3:material3:<version>"

Step 2: Create a Modal Bottom Sheet Layout

@Composable
fun SimpleBottomSheetDemo() {
    val sheetState = rememberModalBottomSheetState(initialValue = ModalBottomSheetValue.Hidden)
    val scope = rememberCoroutineScope()

    ModalBottomSheetLayout(
        sheetState = sheetState,
        sheetContent = {
            Column(
                modifier = Modifier.padding(16.dp).fillMaxWidth(),
                horizontalAlignment = Alignment.CenterHorizontally
            ) {
                Text("Bottom Sheet Content", style = MaterialTheme.typography.body1)
                Spacer(modifier = Modifier.height(8.dp))
                Button(onClick = {
                    scope.launch { sheetState.hide() }
                }) {
                    Text("Close")
                }
            }
        }
    ) {
        Column(
            modifier = Modifier.fillMaxSize(),
            verticalArrangement = Arrangement.Center,
            horizontalAlignment = Alignment.CenterHorizontally
        ) {
            Button(onClick = {
                scope.launch { sheetState.show() }
            }) {
                Text("Show Bottom Sheet")
            }
        }
    }
}

Explanation

  1. ModalBottomSheetLayout: Wraps the content and manages the bottom sheet.

  2. rememberModalBottomSheetState: Controls the sheet’s visibility and state.

  3. CoroutineScope: Handles asynchronous animations (e.g., show() and hide()).

4. Customizing the Bottom Sheet Dialog

Jetpack Compose allows extensive customization:

Styling the Bottom Sheet

You can style the sheet content using modifiers and Material Design components:

sheetContent = {
    Column(
        modifier = Modifier
            .background(Color.White, RoundedCornerShape(topStart = 16.dp, topEnd = 16.dp))
            .padding(16.dp)
            .fillMaxWidth(),
        horizontalAlignment = Alignment.CenterHorizontally
    ) {
        Text("Custom Styled Bottom Sheet", style = MaterialTheme.typography.h6)
        Spacer(modifier = Modifier.height(16.dp))
        Button(onClick = { /* action */ }) {
            Text("Perform Action")
        }
    }
}

Controlling Sheet Behavior

Adjust the behavior with parameters like skipHalfExpanded:

val sheetState = rememberModalBottomSheetState(
    initialValue = ModalBottomSheetValue.Hidden,
    skipHalfExpanded = true
)

Adding Gestures

Enable gestures for a more interactive experience using the Modifier.draggable.

5. Handling State and Events

Managing State

Compose’s state handling is intuitive. Use remember and mutableStateOf to manage data flow:

val isSheetVisible = remember { mutableStateOf(false) }

Listening for State Changes

Monitor state changes with LaunchedEffect:

LaunchedEffect(sheetState.isVisible) {
    if (sheetState.isVisible) {
        // Perform an action when the sheet is shown
    }
}

6. Advanced Use Cases

Integrating with ViewModel

Combine the bottom sheet with a ViewModel to manage business logic:

@Composable
fun BottomSheetWithViewModel(viewModel: MyViewModel) {
    val uiState by viewModel.uiState.collectAsState()

    ModalBottomSheetLayout(
        sheetContent = {
            Text(text = uiState.bottomSheetContent)
        },
        content = { /* Main content */ }
    )
}

Dynamic Content

Populate the bottom sheet dynamically based on user interactions or API responses.

7. Best Practices and Performance Optimization

  1. Keep Content Minimal: Avoid overcrowding the bottom sheet.

  2. Use LazyColumn for Lists: For dynamic content, use LazyColumn to optimize rendering.

  3. Test Responsiveness: Ensure the bottom sheet adapts well to different screen sizes and orientations.

  4. Avoid Nested Scrolls: Use scrollable content cautiously to avoid conflicts.

8. Conclusion

Implementing bottom sheet dialogs in Jetpack Compose is both simple and highly customizable. By leveraging Compose’s declarative nature and state management capabilities, developers can create engaging and responsive bottom sheets that enhance the user experience.

Start experimenting with the examples provided and integrate bottom sheet dialogs into your apps to deliver modern and intuitive UI components!