Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Listen ModalBottomSheetLayout state change in Jetpack Compose

Currently I am using ModalBottomSheetLayout to display the bottom sheet.

I don't know is there a way to listen to the bottom page closing event?

like image 473
MKD Avatar asked Mar 01 '23 11:03

MKD


1 Answers

In Compose to listen for changes you need to check current values of your mutable states.

In case with ModalBottomSheetLayout you have ModalBottomSheetState, and you can check on currentValue of this state. If you need you can modify your views state depending on this value.

If you wanna perform some action on state changes, you need to use side effects. The most basic one is LaunchedEffect, you can use it in combination with snapshotFlow to watch any state value:

LaunchedEffect(Unit) {
    snapshotFlow { modalBottomSheetState.currentValue }
        .collect {
            println(it.toString())
        }
}

Also I'll be called first time when you launch a screen, and you'll have Hidden there too, so depending on your needs it may not be an ideal solution.


To get the most close to listening on becoming hidden, you can use DisposableEffect.

if (modalBottomSheetState.currentValue != ModalBottomSheetValue.Hidden) {
    DisposableEffect(Unit) {
        onDispose {
            println("hidden")
        }
    }
}

Here I'm launching DisposableEffect when your sheet appears, and when it disappears - I'm removing it from the view hierarchy, which will cause the onDispose to be called.

Full example of basically everything you can do with the state:

val modalBottomSheetState = rememberModalBottomSheetState(initialValue = ModalBottomSheetValue.Hidden)
val scope = rememberCoroutineScope()
LaunchedEffect(modalBottomSheetState.currentValue) {
    println(modalBottomSheetState.currentValue)
}
if (modalBottomSheetState.currentValue != ModalBottomSheetValue.Hidden) {
    DisposableEffect(Unit) {
        onDispose {
            println("hidden")
        }
    }
}
ModalBottomSheetLayout(
    sheetState = modalBottomSheetState,
    sheetContent = {
        Text(
            "sheetContent",
            modifier = Modifier.fillMaxHeight()
        )
    }
) {
    Column {
        Text(modalBottomSheetState.currentValue.toString())
        Button(onClick = {
            scope.launch {
                modalBottomSheetState.show()
            }
        }) {
            Text("Show bottom sheet")
        }
    }
}
like image 105
Philip Dukhov Avatar answered Mar 19 '23 08:03

Philip Dukhov