跳转到内容

OverlayListPopup

OverlayListPopup 是 COUI 中的弹出列表组件,用于显示包含多个选项的弹出菜单。它提供了一个轻量级的、浮动的临时列表,适用于各种下拉菜单、上下文菜单等场景。

前置条件

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

引入

kotlin
import io.github.suqi8.coui.kmp.overlay.OverlayListPopup
import io.github.suqi8.coui.kmp.basic.ListPopupColumn
import io.github.suqi8.coui.kmp.basic.ListPopupDefaults
import io.github.suqi8.coui.kmp.basic.DropdownImpl
import io.github.suqi8.coui.kmp.basic.PopupPositionProvider

基本用法

OverlayListPopup 组件可用于创建简单的下拉菜单:

kotlin
var showPopup by remember { mutableStateOf(false) }
var selectedIndex by remember { mutableStateOf(0) }
val items = listOf("Option 1", "Option 2", "Option 3")

Scaffold {
    Box {
        TextButton(
            text = "Click to show menu",
            onClick = { showPopup = true }
        )
        OverlayListPopup(
            show = showPopup,
            alignment = PopupPositionProvider.Align.Start,
            onDismissRequest = { showPopup = false } // Close the popup menu
        ) {
            ListPopupColumn {
                items.forEachIndexed { index, string ->
                    DropdownImpl(
                        text = string,
                        optionSize = items.size,
                        isSelected = selectedIndex == index,
                        index = index,
                        onSelectedIndexChange = {
                            selectedIndex = index
                            showPopup = false // Close the popup menu
                        }
                    )
                }
            }
        }
    }
}

组件状态

不同的对齐方式

OverlayListPopup 可以设置不同的对齐选项:

kotlin
var showPopup by remember { mutableStateOf(false) }

OverlayListPopup(
    show = showPopup,
    onDismissRequest = { showPopup = false }, // Close the popup menu
    alignment = PopupPositionProvider.Align.Start
) {
    ListPopupColumn {
        // Custom content
    }
}

禁用窗口变暗

kotlin
var showPopup by remember { mutableStateOf(false) }

OverlayListPopup(
    show = showPopup,
    onDismissRequest = { showPopup = false }, // Close the popup menu
    enableWindowDim = false // Disable dimming layer
) {
    ListPopupColumn {
        // Custom content
    }
}

上下文菜单定位

除默认的下拉定位器外,ListPopupDefaults.ContextMenuPositionProvider 会将弹窗锚定到锚点的某个角,配合角落对齐方式(TopStart / TopEnd / BottomStart / BottomEnd)使用:

kotlin
var showPopup by remember { mutableStateOf(false) }

OverlayListPopup(
    show = showPopup,
    popupPositionProvider = ListPopupDefaults.ContextMenuPositionProvider,
    alignment = PopupPositionProvider.Align.TopEnd,
    onDismissRequest = { showPopup = false }
) {
    ListPopupColumn {
        // Custom content
    }
}

你也可以通过 ListPopupDefaults.dropdownPositionProvider(verticalMargin, horizontalMargin) 构建带自定义边距的下拉定位器。

属性

OverlayListPopup

属性名类型说明默认值
showBoolean是否显示弹窗-
popupModifierModifier应用于弹窗容器的修饰符Modifier
popupPositionProviderPopupPositionProvider提供弹窗的位置计算逻辑ListPopupDefaults.DropdownPositionProvider
alignmentPopupPositionProvider.Align指定弹窗相对于锚点的对齐方式PopupPositionProvider.Align.Start
enableWindowDimBoolean是否在弹窗显示时使背景变暗true
onDismissRequest(() -> Unit)?当用户请求关闭(例如点击外部)时触发null
onDismissFinished(() -> Unit)?关闭动画完成后调用;若关闭过程被中途取消(例如 show 被设回 true),则不会触发null
maxHeightDp?弹窗内容的最大高度null
minWidthDp弹窗内容的最小宽度ListPopupDefaults.MinWidth
renderInRootScaffoldBoolean是否在根(最外层)Scaffold 中渲染弹窗。为 true 时,弹窗覆盖全屏。为 false 时,在当前 Scaffold 的范围内渲染并进行位置补偿true
content@Composable () -> Unit要在弹窗内显示的内容-

ListPopupColumn

属性名类型说明默认值
content@Composable () -> Unit要在列内显示的列表内容-

DropdownImpl 可作为 ListPopupColumn 内的标准选项行使用。设置 enabled = false 可以禁用某一行;禁用行不可点击,并使用禁用文本颜色。

kotlin
DropdownImpl(
    text = "Disabled option",
    optionSize = items.size,
    isSelected = false,
    index = 1,
    enabled = false,
    onSelectedIndexChange = {}
)

基于文本的重载:

属性名类型说明默认值
textString选项显示文本-
optionSizeInt选项总数-
isSelectedBoolean此选项是否被选中-
indexInt此选项的索引-
dropdownColorsDropdownColors选项颜色配置DropdownDefaults.dropdownColors()
enabledBoolean此选项是否可点击true
dialogModeBoolean是否以对话框模式显示此行false
onSelectedIndexChange(Int) -> Unit点击此选项时的回调-

基于条目的重载接受 DropdownItem(可携带 iconsummary),并暴露额外的布局标志:

属性名类型说明默认值
itemDropdownItem当前选项的条目-
optionSizeInt选项总数-
isSelectedBoolean此选项是否被选中-
indexInt此选项的索引-
dropdownColorsDropdownColors选项颜色配置DropdownDefaults.dropdownColors()
enabledBoolean此选项是否可点击item.enabled
dialogModeBoolean是否以对话框模式显示此行false
hasSubmenuBoolean为 true 时此行作为子菜单触发行:尾部显示 chevron 而非选中对勾false
isFirstBoolean此行是否为整个弹窗的第一行(控制弹窗模式下更大的顶部内边距)index == 0
isLastBoolean此行是否为整个弹窗的最后一行(控制弹窗模式下更大的底部内边距)index == optionSize - 1
onSelectedIndexChange(Int) -> Unit点击此选项时的回调-

PopupPositionProvider.Align

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

ListPopupDefaults 对象

ListPopupDefaults 对象提供弹窗的默认值与定位器。

常量

常量名类型说明
MinWidthDp弹窗的默认最小宽度178.dp
MaxWidthDpListPopupColumn 使用的最大宽度上限232.dp
MinPopupHeightDp弹窗测量时占用的最小高度50.dp

定位器

名称类型说明
DropdownPositionProviderPopupPositionProvider将弹窗锚定在锚点下方(空间不足时上方),用于下拉菜单
ContextMenuPositionProviderPopupPositionProvider将弹窗锚定到锚点的某个角,用于上下文菜单
dropdownPositionProvider(verticalMargin, horizontalMargin)PopupPositionProvider创建带自定义边距的下拉定位器的工厂函数(默认:垂直 8.dp,水平 0.dp)

变更日志

基于 Apache-2.0 许可发布