material3 中底部弹窗ModalBottomSheet

6 篇文章 0 订阅
4 篇文章 0 订阅
本文介绍了如何在MaterialDesign3中正确使用ModalBottomSheet组件,展示了错误的使用方式以及如何通过State管理UI显示和隐藏。重点在于使用`SheetState`和避免在`onDismissRequest`之外手动隐藏,以确保状态清理的正确性。
摘要由CSDN通过智能技术生成

material3 中底部弹窗ModalBottomSheet

由于ModalBottomSheetLayout在material3中被抛弃,所以采用ModalBottomSheet

相关源码

/**
 * <a href="https://m3.material.io/components/bottom-sheets/overview" class="external" target="_blank">Material Design modal bottom sheet</a>.
 *
 * Modal bottom sheets are used as an alternative to inline menus or simple dialogs on mobile,
 * especially when offering a long list of action items, or when items require longer descriptions
 * and icons. Like dialogs, modal bottom sheets appear in front of app content, disabling all other
 * app functionality when they appear, and remaining on screen until confirmed, dismissed, or a
 * required action has been taken.
 *
 * ![外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传](https://img-home.csdnimg.cn/images/20230724024159.png?origin_url=https%3A%2F%2Fdeveloper.android.com%2Fimages%2Freference%2Fandroidx%2Fcompose%2Fmaterial3%2Fbottom_sheet.png&pos_id=img-jRNm94tA-1714121659172)
 *
 * A simple example of a modal bottom sheet looks like this:
 *
 * @sample androidx.compose.material3.samples.ModalBottomSheetSample
 *
 * @param onDismissRequest Executes when the user clicks outside of the bottom sheet, after sheet
 * animates to [Hidden].
 * @param modifier Optional [Modifier] for the bottom sheet.
 * @param sheetState The state of the bottom sheet.
 * @param shape The shape of the bottom sheet.
 * @param containerColor The color used for the background of this bottom sheet
 * @param contentColor The preferred color for content inside this bottom sheet. Defaults to either
 * the matching content color for [containerColor], or to the current [LocalContentColor] if
 * [containerColor] is not a color from the theme.
 * @param tonalElevation The tonal elevation of this bottom sheet.
 * @param scrimColor Color of the scrim that obscures content when the bottom sheet is open.
 * @param dragHandle Optional visual marker to swipe the bottom sheet.
 * @param windowInsets window insets to be passed to the bottom sheet window via [PaddingValues]
 * params.
 * @param content The content to be displayed inside the bottom sheet.
 */
@Composable
@ExperimentalMaterial3Api
fun ModalBottomSheet(
    onDismissRequest: () -> Unit,
    modifier: Modifier = Modifier,
    sheetState: SheetState = rememberModalBottomSheetState(),
    shape: Shape = BottomSheetDefaults.ExpandedShape,
    containerColor: Color = BottomSheetDefaults.ContainerColor,
    contentColor: Color = contentColorFor(containerColor),
    tonalElevation: Dp = BottomSheetDefaults.Elevation,
    scrimColor: Color = BottomSheetDefaults.ScrimColor,
    dragHandle: @Composable (() -> Unit)? = { BottomSheetDefaults.DragHandle() },
    windowInsets: WindowInsets = BottomSheetDefaults.windowInsets,
    content: @Composable ColumnScope.() -> Unit,
) ....

错误示范

@OptIn(ExperimentalMaterial3Api::class)
@Composable
@Preview(showBackground = true, name = "TestImageShare", group = "test")
fun TestImageShare(){
    // 分享
    val sheetState = rememberModalBottomSheetState();
    val scope = rememberCoroutineScope()
    Row {
        Button(onClick = { scope.launch {  sheetState.show()} }) {
            Text(text = "打开底部弹出")
        }
        Button(onClick = { scope.launch {  sheetState.hide()} }) {
            Text(text = "关闭底部弹出")
        }
    }
    ModalBottomSheet(
        onDismissRequest = {
         	scope.launch {  sheetState.hide()}
        },
        sheetState=sheetState
    ){
        LazyVerticalGrid(
            columns = GridCells.Adaptive(minSize = 128.dp),
            modifier = Modifier
        ){
            item(1){
                Column(horizontalAlignment = Alignment.CenterHorizontally) {
                    Image(
                        painter =
                        painterResource(id = R.drawable.test),
                        alignment = Alignment.Center,
                        contentScale = ContentScale.Crop,
                        contentDescription = null,
                        modifier = Modifier
                            .height(80.dp)
                            .padding(5.dp)
                    )
                    Text(
                        text = "微信",
                        color = Color.Black
                    )
                }
            }
        }
    }

}

加载ModalBottomSheet时候已经弹出,sheetState没有起到效果

在这里插入图片描述

正确操作

通过State来重新重组ui,实现点击开启,点击关闭的结果,
如果你在on遣散请求之外提供逻辑来删除表单,你必须额外处理预期的状态清理,才能使用sheetState.hide()进行清理

// 分享
val sheetState = rememberModalBottomSheetState();
var visible by remember {
    mutableStateOf(false)
}
Row {
    Button(onClick = {visible = !visible
    }) {
        Text(text = "打开底部弹出")
    }
}

if (visible) {
    ModalBottomSheet(
        onDismissRequest = {
            visible = false
        },
        sheetState = sheetState
    ) {
        Column(horizontalAlignment = Alignment.CenterHorizontally) {
            Image(
                painter =
                painterResource(id = R.drawable.test),
                alignment = Alignment.Center,
                contentScale = ContentScale.Crop,
                contentDescription = null,
                modifier = Modifier
                    .height(80.dp)
                    .padding(5.dp)
            )
            Text(
                text = "微信",
                color = Color.Black
            )
        }

    }
}

在这里插入图片描述

  • 8
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值