跳转到内容

OverlayCascadingListPopup

OverlayCascadingListPopup 是支持二级菜单的弹出列表组件。DropdownItem.children 非空的项会成为子菜单触发器:点击后弹窗会以触发行为锚点变形为二级列表,主列表则缩小并被半透明遮罩覆盖。级联深度限制为 2 级

前置条件

此组件依赖于 Scaffold 提供的 MiuixPopupHost 来渲染弹窗内容。必须在 Scaffold 内部使用,否则弹窗内容将无法正常渲染。

引入

kotlin
import top.yukonga.miuix.kmp.overlay.OverlayCascadingListPopup
import top.yukonga.miuix.kmp.basic.DropdownEntry
import top.yukonga.miuix.kmp.basic.DropdownItem

基本用法

构造 entries,让某些 DropdownItem 携带非空的 children 列表。组件会在这些触发行的尾部渲染向右的 chevron;点击触发行后会就地展开二级菜单。

kotlin
var showPopup by remember { mutableStateOf(false) }
var sortIndex by remember { mutableStateOf(0) }
var viewIndex by remember { mutableStateOf(0) }

val sortLabels = listOf("按拍摄日期排序", "按添加日期排序")
val viewLabels = listOf("按日期分组", "紧凑视图")
val entries = listOf(
    DropdownEntry(
        items = sortLabels.mapIndexed { idx, label ->
            DropdownItem(
                text = label,
                selected = sortIndex == idx,
                onClick = { sortIndex = idx },
            )
        },
    ),
    DropdownEntry(
        items = listOf(
            DropdownItem(
                text = "查看模式",
                children = viewLabels.mapIndexed { idx, label ->
                    DropdownItem(
                        text = label,
                        selected = viewIndex == idx,
                        onClick = { viewIndex = idx },
                    )
                },
            ),
        ),
    ),
)

Scaffold {
    Box {
        TextButton(
            text = "点击显示菜单",
            onClick = { showPopup = true },
        )
        OverlayCascadingListPopup(
            show = showPopup,
            entries = entries,
            onDismissRequest = { showPopup = false },
        )
    }
}

级联深度

级联深度上限为 2。二级菜单中的项不会再处理自己的 children;更深层的子树会被静默忽略。

组件状态

不同的对齐方式

kotlin
OverlayCascadingListPopup(
    show = showPopup,
    entries = entries,
    onDismissRequest = { showPopup = false },
    alignment = PopupPositionProvider.Align.Start,
)

禁用窗口变暗

kotlin
OverlayCascadingListPopup(
    show = showPopup,
    entries = entries,
    onDismissRequest = { showPopup = false },
    enableWindowDim = false,
)

选中后保持弹窗打开

默认情况下,用户点击任何一个叶子项后弹窗会自动关闭。设为 collapseOnSelection = false 即可保持弹窗打开(例如二级菜单内的多选)。

kotlin
OverlayCascadingListPopup(
    show = showPopup,
    entries = entries,
    onDismissRequest = { showPopup = false },
    collapseOnSelection = false,
)

属性

OverlayCascadingListPopup

属性名类型说明默认值
showBoolean是否显示弹窗-
entriesList<DropdownEntry>由分割线分组的下拉条目;顶层中 children 非空的项会成为子菜单触发行-
onDismissRequest() -> Unit用户请求关闭(点击外部、触发返回等)时调用-
popupModifierModifier应用于弹窗主体的修饰符Modifier
onDismissFinished(() -> Unit)?退出动画结束后调用null
popupPositionProviderPopupPositionProvider主弹窗相对锚点的定位策略ListPopupDefaults.DropdownPositionProvider
alignmentPopupPositionProvider.Align主弹窗的对齐方式PopupPositionProvider.Align.End
enableWindowDimBoolean弹窗显示时是否变暗背景true
maxHeightDp?任一面的最大高度。null 时由安全区限制null
minWidthDp弹窗的最小宽度200.dp
renderInRootScaffoldBoolean是否在根(最外层)Scaffold 中渲染弹窗。为 true 时,弹窗覆盖全屏。为 false 时,在当前 Scaffold 的范围内渲染并进行位置补偿true
dropdownColorsDropdownColors每一行使用的颜色配置DropdownDefaults.dropdownColors()
collapseOnSelectionBoolean为 true 时,选中任何叶子项后即关闭弹窗true
属性名类型说明默认值是否必须
itemsList<DropdownItem>此分组中显示的条目-
enabledBoolean此分组是否启用。为 false 时禁用整组条目;为 true 时仍会遵循每个条目的 enabled 状态true
属性名类型说明默认值是否必须
textString选项显示的文本-
enabledBoolean选项是否可点击,禁用时置灰true
selectedBoolean选项是否处于选中状态false
onClick(() -> Unit)?点击选项时触发的回调。当 children 非空时被忽略(点击会改为展开二级菜单)null
icon@Composable ((Modifier) -> Unit)?显示在选项文本前的图标null
summaryString?显示在选项文本下方的摘要文本null
childrenList<DropdownItem>?可选的子菜单项;仅级联变体会将其渲染为二级菜单(最多两级)null
属性名类型说明
contentColorColor选项标题颜色
summaryColorColor选项摘要颜色
containerColorColor选项背景颜色
selectedContentColorColor选中项标题颜色
selectedSummaryColorColor选中项摘要颜色
selectedContainerColorColor选中项背景颜色
selectedIndicatorColorColor选中指示图标颜色

PopupPositionProvider.Align

说明
Start将弹窗对齐到锚点的起始端
End将弹窗对齐到锚点的结束端
TopStart将弹窗对齐到锚点的顶部起始端
TopEnd将弹窗对齐到锚点的顶部结束端
BottomStart将弹窗对齐到锚点的底部起始端
BottomEnd将弹窗对齐到锚点的底部结束端

变更日志

基于 Apache-2.0 许可发布