Jetpack Compose中BottomSheet内SelectionContainer不显示选中选项问题
解决方法
这个问题的核心原因是**ModalBottomSheet的内部布局拦截了文本选择后的上下文菜单事件**,导致系统无法正常弹出操作菜单。可以通过以下两种方式解决:
方法一:手动绑定文本工具栏锚点
在ModalBottomSheet的内容布局中,通过LocalTextToolbar将上下文菜单锚定到BottomSheet的区域,绕过事件拦截:
@OptIn(ExperimentalMaterial3Api::class) @Composable fun BottomSheet( showSheet: Boolean, onDismiss: () -> Unit, ) { val modalBottomSheetState = rememberModalBottomSheetState() val textToolbar = LocalTextToolbar.current if (showSheet) { ModalBottomSheet( onDismissRequest = { onDismiss() }, sheetState = modalBottomSheetState, dragHandle = { BottomSheetDefaults.DragHandle() }, ) { Column( modifier = Modifier .fillMaxSize() .background(MaterialTheme.colorScheme.tertiary) // 绑定工具栏锚点到BottomSheet的布局范围 .onGloballyPositioned { coordinates -> textToolbar.setAnchorRect(coordinates.boundsInWindow()) } ) { SelectionContainer { Text( text = "muh text", color = Color.Black, modifier = Modifier .padding(10.dp) .verticalScroll(rememberScrollState()), style = MaterialTheme.typography.displayMedium, textAlign = TextAlign.Right, ) } } } } }
方法二:替换为BottomSheetScaffold(推荐)
如果业务场景允许,使用BottomSheetScaffold替代ModalBottomSheet,它对文本选择的上下文菜单支持更完善,无需额外配置:
@OptIn(ExperimentalMaterial3Api::class) @Composable fun BottomSheetScaffoldExample( showSheet: Boolean, onDismiss: () -> Unit, ) { val scope = rememberCoroutineScope() val sheetState = rememberStandardBottomSheetState( initialValue = if (showSheet) SheetValue.Expanded else SheetValue.Hidden ) // 根据showSheet状态控制弹窗展开/隐藏 LaunchedEffect(showSheet) { if (showSheet) sheetState.expand() else sheetState.hide() } BottomSheetScaffold( sheetContent = { Column( modifier = Modifier .fillMaxWidth() .background(MaterialTheme.colorScheme.tertiary) ) { SelectionContainer { Text( text = "muh text", color = Color.Black, modifier = Modifier .padding(10.dp) .verticalScroll(rememberScrollState()), style = MaterialTheme.typography.displayMedium, textAlign = TextAlign.Right, ) } } }, sheetState = sheetState, sheetDragHandle = { BottomSheetDefaults.DragHandle() }, onSheetHidden = onDismiss ) { // 此处放置主页面内容 } }
原因说明
ModalBottomSheet的内部实现中,弹窗的窗口层级和事件分发逻辑会阻止文本选择工具栏的正常渲染。而BottomSheetScaffold基于Scaffold的布局体系,与系统上下文菜单的兼容性更好;手动绑定LocalTextToolbar则是强制将菜单锚点指向BottomSheet的布局区域,从而绕过事件拦截。
内容的提问来源于stack exchange,提问作者M.KH
相关产品推荐
相关产品推荐

