监听 Jetpack Compose 中的 ModalBottomSheetLayout 状态更改

MKD*_*MKD 32 android android-jetpack-compose

目前我正在使用 ModalBottomSheetLayout 来显示底部工作表。

不知道有没有办法监听底部页面关闭事件?

Phi*_*hov 48

在 Compose 中要监听更改,您需要检查可变状态的当前值。

如果ModalBottomSheetLayout您有ModalBottomSheetState,您可以检查currentValue此状态。如果需要,您可以根据该值修改视图状态。

如果你想对状态变化执行一些操作,你需要使用副作用。最基本的是LaunchedEffect,您可以将它与 结合使用snapshotFlow来观察任何状态值:

LaunchedEffect(Unit) {
    snapshotFlow { modalBottomSheetState.currentValue }
        .collect {
            println(it.toString())
        }
}
Run Code Online (Sandbox Code Playgroud)

另外,当您启动屏幕时,我会第一次被呼叫,并且您也会Hidden在那里,所以根据您的需要,它可能不是一个理想的解决方案。


要最接近地聆听隐藏状态,您可以使用DisposableEffect

if (modalBottomSheetState.currentValue != ModalBottomSheetValue.Hidden) {
    DisposableEffect(Unit) {
        onDispose {
            println("hidden")
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

DisposableEffect在这里,当您的工作表出现和消失时,我将启动- 我将其从视图层次结构中删除,这将导致onDispose被调用。

基本上您可以对状态执行的所有操作的完整示例:

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")
        }
    }
}
Run Code Online (Sandbox Code Playgroud)


Sen*_*ian 29

您可以只使用confirmStateChange来自rememberModalBottomSheetState

val state = rememberModalBottomSheetState(ModalBottomSheetValue.Hidden, confirmStateChange = {
   if (it == ModalBottomSheetValue.Hidden) {
       println(it)
   }
   true
})
Run Code Online (Sandbox Code Playgroud)


lec*_*909 11

但是,如果您自己使用模态,则confirmStateChange不会调用使用- 例如,它似乎仅在单击稀松布或滑动时才会调用。show/hideclickable

解决这个问题的方法是观察modalBottomSheetState.targetValue模态在两种不同状态之间动画时会发生的变化:

LaunchedEffect(modalBottomSheetState.targetValue) {
    if (modalBottomSheetState.targetValue == ModalBottomSheetValue.Hidden) {
        // do something when animating to Hidden state
      } else {
        // expanding
      }
}
Run Code Online (Sandbox Code Playgroud)

这更接近于confirmStateChange调用之前调用的时间show/hide。观察modalBottomSheetState.currentValue会在动画结束时发生变化,而modalBottomSheetState.targetValue在动画开始之前会发生变化。