Jetpack Compose ModalBottomSheetLayout onCancel event

1.7k Views Asked by At

I'm using ModalBottomSheetLayout

@Composable
fun BottomSheetWrapper() {
    ModalBottomSheetLayout(
    sheetState = sheetState,
    sheetContent = {
        Spacer(modifier = Modifier.height(1.dp))
        content()
    },
    modifier = modifier,
    content = {}
)}

and I want to trigger some logic when user dismisses the bottomsheet (back press or touch outside of the bottomsheet). In another words I need something similar to onCancel event of BottomSheetDialogFragment.

What would be the best way to do it with ModalBottomsheetLayout?

1

There are 1 best solutions below

1
On

You can use the sheetState object to observe the state changes of the ModalBottomSheetLayout and trigger the required logic when the bottom sheet is dismissed by the user. The sheetState object contains an isExpanded property that can be used to check whether the bottom sheet is expanded or not.

To listen for the bottom sheet dismissal event, you can add a DisposableEffect composable that will execute a callback function when the bottom sheet is dismissed. The DisposableEffect composable is used to perform a side effect when a composable is added or removed from the composition.

@Composable
fun BottomSheetWrapper(onDismiss: () -> Unit) {
    val sheetState = rememberModalBottomSheetState(initialValue = ModalBottomSheetValue.Hidden)
    
    // Listen for the bottom sheet dismissal event
    DisposableEffect(sheetState) {
        val callback = ModalBottomSheetCallback(onDismiss)
        sheetState.addOnDismissedListener(callback)
        onDispose { sheetState.removeOnDismissedListener(callback) }
    }
    
    ModalBottomSheetLayout(
        sheetState = sheetState,
        sheetContent = {
            Spacer(modifier = Modifier.height(1.dp))
            content()
        },
        modifier = modifier,
        content = {}
    )
}

class ModalBottomSheetCallback(private val onDismiss: () -> Unit) :
    ModalBottomSheetState.BottomSheetStateCallback {
    override fun onStateChanged(bottomSheet: ModalBottomSheetState, newState: ModalBottomSheetValue) {
        if (newState == ModalBottomSheetValue.Hidden) {
            onDismiss()
        }
    }
}

In this implementation, the BottomSheetWrapper composable takes an onDismiss lambda as a parameter that will be called when the bottom sheet is dismissed. We use the DisposableEffect composable to add and remove a ModalBottomSheetCallback that will listen for the bottom sheet dismissal event. When the bottom sheet is dismissed, the onDismiss lambda is called.