Android Compose: 关闭底部弹出窗口时,使用拖动或返回键会导致屏幕冻结。

3
我正在使用Jetpack Compose开发一个Android应用程序,遇到了一个问题。当我与底部弹出窗口进行交互(向下拖动或使用返回按钮关闭它)时,我的屏幕变得无响应,直到我重新启动应用程序才能正常工作。这种行为是不符合预期的,我正在努力找出根本原因。以下是相关细节:
这是底部弹出窗口:
fun BottomSheet(
    onDismiss: () -> Unit
) {
    val bottomSheetState = rememberModalBottomSheetState(skipPartiallyExpanded = true)  
    val scope = rememberCoroutineScope()
    
    scope.launch {
            bottomSheetState.expand()
    }
    
    ModalBottomSheet(
        onDismissRequest = { onDismiss() },
        sheetState = bottomSheetState,
        dragHandle = { BottomSheetDefaults.DragHandle() }
    ) {
             ColorPicker()     
    }
    
}```

这是它打开的地方:

Scaffold(
modifier = Modifier.fillMaxSize(),
scaffoldState = scaffoldState,
topBar = {
AppBar(
...
)
},
content = { paddingValue -\>

            Box(
                modifier = Modifier
                    .fillMaxSize()
                    .padding(
                        top = paddingValue.calculateTopPadding(),
                    )
            ) {
                Column(
                    modifier = Modifier
                        .fillMaxWidth()
                        .padding(16.dp)
                        .verticalScroll(rememberScrollState())
                
                ) {
                    // Night Mode setting Section
                        ...
                    // Font setting Section
                        ...
                    // color setting Section
    
                        CustomCard(
                            title = "Color",
                            isExpandedInitially = fontColorSettingExpand,
                            onItemClick = {
                                fontColorSettingExpand = !fontColorSettingExpand
                            }) {
                            BottomSheet(
                                navController = navController,
                                onDismiss = {
                                    //todo save
                                })

}```

我尝试过的方法:
- 检查了我的状态管理,确保它是正确的。 - 回顾了我的协程使用情况,以防有任何潜在的阻塞问题。 - 确认我正在使用适当的Compose组件和ScaffoldState。

使用BottomSheetScaffold。 https://www.composables.com/components/material3/bottomsheetscaffold - undefined
我猜你的问题出在onDismiss方法中,你在注释中写了"todo save"。可能是因为你在onDismiss回调中在UI线程上执行了IO操作。为了测试这个问题,你可以将onDismiss方法中的所有代码注释掉,看看问题是否解决。 - undefined
在我的代码中,那一行仍然是"待办事项",我在那里什么都没做。@Amani - undefined
3个回答

0
Amani的回答导致Modal在我的设备上没有动画效果。这个无响应的屏幕似乎是Material3中的一个bug,在版本1.2.0-alpha08中已经修复,发布说明中提到:

修复了一个bug,当通过向下滑动面板来关闭ModalBottomSheet时,没有调用onDismissedRequest

将Material3更新到版本1.2.0-alpha08或版本1.2.0-alpha10(发布时的最新版本)解决了这个问题,而无需使用任何if语句或LaunchedEffect

0
你遇到的问题是你在函数的组合内调用了bottomSheetState.expand(),所以当你进行Dismiss或Drag操作时,这段代码会一遍又一遍地执行,导致屏幕冻结。
要解决这个问题,你可以在LaunchedEffect中调用bottomSheetState.expand(),这样它就在组合之外运行。代码如下所示:
fun BottomSheet(
    onDismiss: () -> Unit
) {
    val bottomSheetState = rememberModalBottomSheetState(skipPartiallyExpanded = true)
    
    ModalBottomSheet(
        onDismissRequest = { onDismiss() },
        sheetState = bottomSheetState,
        dragHandle = { BottomSheetDefaults.DragHandle() }
    ) {
             ColorPicker()     
    }

  LaunchedEffect(key1 = Unit, block = {
     bottomSheetState.expand()
  })
    
}

注意:
在寻求帮助时,要小心暴露的代码,因为第一个代码片段显示BottomSheet只有onDismiss作为参数,而第二个代码片段反映出你正在传递一个navController(这是不推荐的),你应该暴露一个lambda,然后执行必要的操作,但BottomSheet不应该处理导航),所以如果你展示的代码不是最新的,很难找到可能的错误。

非常感谢您建议在组合外部使用LaunchedEffect来调用bottomSheetState.expand()。我按照您提到的更改进行了应用,但不幸的是,我仍然在屏幕上遇到冻结问题。您说得对,我确实忘记删除对navController的引用,实际上,我在我的代码中没有它。 - undefined

0
ModalBottomSheet添加到仅在可见时进行组合。使用以下条件来解决您的问题:
fun BottomSheet(
    onDismiss: () -> Unit
) {
    val bottomSheetState = rememberModalBottomSheetState(skipPartiallyExpanded = true) 
    LaunchedEffect(key1 = Unit) {
            bottomSheetState.expand()
    }
    
    if (bottomSheetState.isVisible) //<-- add this condition to add sheet only when it is visible
        ModalBottomSheet(
             onDismissRequest = { onDismiss() },
             sheetState = bottomSheetState,
             dragHandle = { BottomSheetDefaults.DragHandle() }
         ) {
             ColorPicker()     
           }
    
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接