compose-material3 实现Dropwmenu下拉菜单并弹窗

4 篇文章 0 订阅
4 篇文章 0 订阅

在这里插入图片描述

Dropwmenu 下拉菜单

下拉菜单的行为类似于弹出窗口,并将使用父布局的位置来定位自己在屏幕上的位置。通常,下拉菜单将被放置在一个具有兄弟框的框中,该框将被用作“锚”。请注意,DropdownMenu本身不会占用布局中的任何空间,因为菜单显示在一个单独的窗口中,位于其他内容的顶部。
DropdownMenu的内容通常是DropdownMenuItems,以及自定义内容。使用DropdownMenuItems将产生一个与菜单材质规范匹配的菜单。还要注意,内容被放置在一个可滚动的Column中,因此不支持使用LazyColumn作为内容中的根布局。
当菜单应该关闭时,on遣散请求将被调用——例如,当有一个菜单外的点击,或者当返回键被按下。
下拉菜单根据可用空间改变其位置,始终试图完全可见。根据布局方向,它将尝试水平扩展到其父元素的末尾,然后扩展到其父元素的开始,然后扩展到屏幕末端对齐。在垂直方向上,它将尝试扩展到其父元素的底部,然后从其父元素的顶部扩展到屏幕顶部对齐。当父菜单的布局边界与其视觉边界不一致时,可以提供一个偏移量来调整菜单的位置。注意,偏移量将应用于菜单决定展开的方向。

@Suppress("ModifierParameter")
@Composable
fun DropdownMenu(
    expanded: Boolean,
    onDismissRequest: () -> Unit,
    modifier: Modifier = Modifier,
    offset: DpOffset = DpOffset(0.dp, 0.dp),
    properties: PopupProperties = PopupProperties(focusable = true),
    content: @Composable ColumnScope.() -> Unit
){
    val expandedStates = remember { MutableTransitionState(false) }
    expandedStates.targetState = expanded

    if (expandedStates.currentState || expandedStates.targetState) {
        val transformOriginState = remember { mutableStateOf(TransformOrigin.Center) }
        val density = LocalDensity.current
        val popupPositionProvider = DropdownMenuPositionProvider(
            offset,
            density
        ) { parentBounds, menuBounds ->
            transformOriginState.value = calculateTransformOrigin(parentBounds, menuBounds)
        }

        Popup(
            onDismissRequest = onDismissRequest,
            popupPositionProvider = popupPositionProvider,
            properties = properties
        ) {
            DropdownMenuContent(
                expandedStates = expandedStates,
                transformOriginState = transformOriginState,
                modifier = modifier,
                content = content
            )
        }
    }
}

NameDescriptionexpanded菜单是否展开onDismissRequest当用户请求取消菜单时调用,例如在菜单边界外点击offset偏移量

Dialog对话框

打开具有给定内容的对话框。
只要对话框是复合层次结构的一部分,它就是可见的。为了让用户取消对话框,onCloseRequest的实现应该包含一个方法来删除从组合层次结构中删除对话框。

@Composable
fun Dialog(
    onDismissRequest: () -> Unit,
    properties: DialogProperties = DialogProperties(),
    content: @Composable () -> Unit
)

onCloseRequest 当用户试图取消对话框时执行。
properties 进一步配置定制对话框的动画,点击边界关闭,后退关闭等等
content 要在对话框中显示的内容

核心代码如下

通过expanded 状态开启下拉菜单,onDismissRequest 在试图关闭的时候修改状态进行关闭,然后selectedIndex 进行开启对话框等等

TopAppBar(
    colors = TopAppBarDefaults.topAppBarColors(
        containerColor = MaterialTheme.colorScheme.primaryContainer,
        titleContentColor = MaterialTheme.colorScheme.primary,
    ),
    title = {
        Row {
            Row {
                Button(
                    onClick = { settingDrawerState = DrawerState(DrawerValue.Open) },
                    modifier = Modifier.size(40.dp),
                    shape = RoundedCornerShape(50),
                    contentPadding = PaddingCommon.ZERO_PADDING,
                    colors = ButtonDefaults.buttonColors(Color.White)
                ) {
                    Surface(
                        shape = CircleShape,
                        border = BorderStroke(0.dp, Color.Gray)
                    ) {
                        Image(
                            painter = painterResource(id = R.drawable.test),
                            contentDescription = null,
                            modifier = Modifier.size(40.dp),
                            contentScale = ContentScale.Crop
                        )
                    }
                }
                TextButton(
                    onClick = { /*TODO*/ },
                    contentPadding = PaddingCommon.ZERO_PADDING,
                ) {
                    Text(text = "白")
                }
            }
            Row(
                horizontalArrangement = Arrangement.End,
                modifier = Modifier.fillMaxWidth()
            ) {
                Column {
                    IconButton(onClick = { expanded = true }) {
                        Icon(
                            modifier = Modifier
                                .padding(0.dp)
                                .fillMaxSize(),
                            imageVector = Icons.Filled.Add,
                            contentDescription = "Localized description"
                        )
                    }
                    DropdownMenu(
                        expanded = expanded,
                        onDismissRequest = { expanded = false }) {
                        items.forEachIndexed { index, label ->
                            DropdownMenuItem(text = {
                                Text(text = label)
                            }, onClick = {
                                selectedIndex = index
                                expanded = false
                            })
                        }
                    }
                }
                if (selectedIndex == 1) {
                    DialogImageAdd(onDismissRequest = {
                        selectedIndex = 0
                    })
                }
            }
        }
    }
)


@Composable
fun DialogImageAdd(
    onDismissRequest: () -> Unit,
    properties: DialogProperties = DialogProperties(),
) =
    Dialog(onDismissRequest = onDismissRequest, properties = properties) {
        var text by rememberSaveable { mutableStateOf("") }
        Box(
            modifier = Modifier
                .background(Color.White)
                .padding(10.dp)
        ) {
            Column() {
                Row(horizontalArrangement = Arrangement.Center) {
                    Text(text = "创建文件夹")
                }
                Row() {
                    OutlinedTextField(value = text, onValueChange = { text = it }, label = {
                        Text(text = "名称")
                    })
                }
                Button(onClick = {
                    val file = File("./images/${text}")
                    if (!file.exists()) {
                        file.mkdir()
                    }
                }) {
                    Text(text = "确定")
                }
            }
        }
    }

演示

在这里插入图片描述

在这里插入图片描述

  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值