我正在尝试将 Material3 中的
ModalBottomSheet
添加到我的应用程序中。
我有一个像这样实现的主屏幕:
@Composable
fun MainScreen() {
Surface(
modifier = Modifier.fillMaxSize(),
color = MaterialTheme.colorScheme.background
) {
Scaffold(
content = {},
modifier = Modifier.fillMaxSize()
)
}
SignInBottomSheet()
}
和登录底表:
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun SignInBottomSheet(
) {
ModalBottomSheet(
onDismissRequest = {}
) {
Column(
modifier = Modifier.align(Alignment.CenterHorizontally)
) {
Button(
modifier = Modifier
.width(200.dp)
.height(70.dp)
.padding(bottom = 10.dp),
onClick = { /*TODO*/ }
) {
Text(
text = "Log in",
style = MaterialTheme.typography.bodyLarge,
fontWeight = FontWeight.Bold
)
}
Button(
onClick = { /*TODO*/ },
modifier = Modifier
.width(200.dp)
.height(70.dp)
.padding(bottom = 10.dp),
) {
Text(
text = "Continue with Google",
style = MaterialTheme.typography.bodyLarge,
fontWeight = FontWeight.Bold
)
}
}
}
}
应用程序启动时,底部工作表可见,当我点击底部工作表外部时,底部工作表会折叠,但它保留在屏幕底部,与系统按钮的一部分重叠。
我没有添加任何
remember
对象,因为我得到了与该对象相同的行为,唯一的区别是底部工作表在一段时间后消失(但捕捉仍然可见)。
下面是打开和关闭底部纸张的图像(仔细观察屏幕底部)。
看起来这个问题已在 Compose Material 3 版本 1.2.0-alpha02 中解决。
查看发行说明中的以下部分:
向 ModalBottomSheet 添加窗口插入参数。
但是,鉴于它是一个 alpha 库,并不是每个人都愿意更新它。
我为他们创建了一个问题跟踪器,将修复程序向后移植到 1.1.0。
默认情况下,他们不会隐藏 ModalBottomSheet,在文档中,他们还维护 if 条件来解决问题。
我们需要维护状态 - var openBottomSheet by RememberSaveable { mutableStateOf(false) }
根据 Bottomsheet 关闭和打开更改状态。
通过使用 if 条件或动画可见性来修复 Bottom Sheet 重叠问题。
var openBottomSheet by rememberSaveable { mutableStateOf(false) }
var skipPartiallyExpanded by remember { mutableStateOf(false) }
val scope = rememberCoroutineScope()
val bottomSheetState = rememberModalBottomSheetState(
skipPartiallyExpanded = skipPartiallyExpanded
)
// App content
Column(
modifier = Modifier.fillMaxSize(),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.Center
) {
Row(
Modifier.toggleable(
value = skipPartiallyExpanded,
role = Role.Checkbox,
onValueChange = { checked -> skipPartiallyExpanded = checked }
)
) {
Checkbox(checked = skipPartiallyExpanded, onCheckedChange = null)
Spacer(Modifier.width(16.dp))
Text("Skip partially expanded State")
}
Button(onClick = { openBottomSheet = !openBottomSheet }) {
Text(text = "Show Bottom Sheet")
}
}
// Sheet content
if (openBottomSheet) {
ModalBottomSheet(
onDismissRequest = { openBottomSheet = false },
sheetState = bottomSheetState,
) {
Row(Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.Center) {
Button(
// Note: If you provide logic outside of onDismissRequest to remove the sheet,
// you must additionally handle intended state cleanup, if any.
onClick = {
scope.launch { bottomSheetState.hide() }.invokeOnCompletion {
if (!bottomSheetState.isVisible) {
openBottomSheet = false
}
}
}
) {
Text("Hide Bottom Sheet")
}
}
var text by remember { mutableStateOf("") }
OutlinedTextField(value = text, onValueChange = { text = it })
LazyColumn {
items(50) {
ListItem(
headlineContent = { Text("Item $it") },
leadingContent = {
Icon(
Icons.Default.Favorite,
contentDescription = "Localized description"
)
}
)
}
}
}
}
除了 If 条件,我们还可以使用 AnimatedVisibility。