跳转到内容

OverlaySpinnerPreference

OverlaySpinnerPreference 是 Miuix 中的下拉选择器组件,提供了标题、摘要和带有图标、文本的选项列表,支持点击交互和多种显示模式,常用于具有视觉辅助的选项设置中。该组件与 OverlayDropdownPreference 组件类似,但提供更丰富的功能和交互体验。

使用前提

此组件依赖 Scaffold 提供的 MiuixPopupHost 以显示弹出内容。必须在 Scaffold 中使用,否则弹出内容无法正常渲染。

引入

kotlin
import top.yukonga.miuix.kmp.preference.OverlaySpinnerPreference
import top.yukonga.miuix.kmp.basic.DropdownEntry
import top.yukonga.miuix.kmp.basic.DropdownItem

基本用法

OverlaySpinnerPreference 组件提供了基础的下拉选择器功能:

kotlin
var selectedIndex by remember { mutableStateOf(0) }
val options = listOf(
    DropdownItem(text = "选项 1"),
    DropdownItem(text = "选项 2"),
    DropdownItem(text = "选项 3"),
)

Scaffold {
    OverlaySpinnerPreference(
        title = "下拉选择器",
        items = options,
        selectedIndex = selectedIndex,
        onSelectedIndexChange = { selectedIndex = it }
    )
}

带图标和摘要的选项

kotlin
// 创建一个圆角矩形的 Painter
class RoundedRectanglePainter(
    private val cornerRadius: Dp = 6.dp
) : Painter() {
    override val intrinsicSize = Size.Unspecified

    override fun DrawScope.onDraw() {
        drawRoundRect(
            color = Color.White,
            size = Size(size.width, size.height),
            cornerRadius = CornerRadius(cornerRadius.toPx(), cornerRadius.toPx())
        )
    }
}

var selectedIndex by remember { mutableStateOf(0) }
val options = listOf(
    DropdownItem(
        icon = { Icon(RoundedRectanglePainter(), "Icon", Modifier.padding(end = 12.dp), Color(0xFFFF5B29)) },
        text = "红色主题",
        summary = "活力四射的红色"
    ),
    DropdownItem(
        icon = { Icon(RoundedRectanglePainter(), "Icon", Modifier.padding(end = 12.dp), Color(0xFF3482FF)) },
        text = "蓝色主题",
        summary = "沉稳冷静的蓝色"
    ),
)

Scaffold {
    OverlaySpinnerPreference(
        title = "功能选择",
        summary = "选择您要执行的操作",
        items = options,
        selectedIndex = selectedIndex,
        onSelectedIndexChange = { selectedIndex = it }
    )
}

组件状态

禁用状态

kotlin
OverlaySpinnerPreference(
    title = "禁用选择器",
    summary = "此选择器当前不可用",
    items = listOf(DropdownItem(text = "选项 1")),
    selectedIndex = 0,
    onSelectedIndexChange = {},
    enabled = false
)

对话框模式

OverlaySpinnerPreference 还支持对话框模式,适用于显示较多选项或需要更醒目的选择界面时。通过提供 dialogButtonString 参数即可激活此模式。

kotlin
var selectedIndex by remember { mutableStateOf(0) }
val options = listOf(
    DropdownItem(text = "选项 A"),
    DropdownItem(text = "选项 B"),
    DropdownItem(text = "选项 C")
)

Scaffold {
    OverlaySpinnerPreference(
        title = "对话框模式",
        dialogButtonString = "取消",
        items = options,
        selectedIndex = selectedIndex,
        onSelectedIndexChange = { selectedIndex = it }
    )
}

分组选项

当选项需要选中状态、禁用状态、点击回调、图标或摘要时,可以使用 DropdownEntry。使用 entries 可以显示多个分组,分组之间会用分割线隔开。

kotlin
var firstSelectedIndex by remember { mutableStateOf(0) }
var secondSelectedIndex by remember { mutableStateOf(0) }
val entries = listOf(
    DropdownEntry(
        items = listOf("小", "中").mapIndexed { index, text ->
            DropdownItem(text = text, selected = firstSelectedIndex == index, onClick = { firstSelectedIndex = index })
        }
    ),
    DropdownEntry(
        items = listOf("红色", "绿色", "蓝色").mapIndexed { index, text ->
            DropdownItem(text = text, selected = secondSelectedIndex == index, onClick = { secondSelectedIndex = index })
        }
    )
)

Scaffold {
    OverlaySpinnerPreference(
        title = "分组选项",
        entries = entries,
        collapseOnSelection = false
    )
}

对于 entries 重载,collapseOnSelection 控制点击选项后是否关闭弹出框。默认值为 entries.size <= 1,单个分组会在选中后关闭,多个分组会保持打开以便连续选择。提供 dialogButtonString 后,对话框模式也支持相同的 entryentries 重载。

多选

因为选中状态放在 DropdownItem 上,可以用集合保存多个选中值,并在每个条目的 onClick 中切换选中状态。

kotlin
var selectedItems by remember { mutableStateOf(setOf("A1", "B2")) }
val entries = listOf(
    DropdownEntry(
        items = listOf("A1", "A2").map { text ->
            DropdownItem(
                text = text,
                selected = text in selectedItems,
                onClick = {
                    selectedItems = if (text in selectedItems) selectedItems - text else selectedItems + text
                }
            )
        }
    ),
    DropdownEntry(
        items = listOf("B1", "B2", "B3").map { text ->
            DropdownItem(
                text = text,
                selected = text in selectedItems,
                onClick = {
                    selectedItems = if (text in selectedItems) selectedItems - text else selectedItems + text
                }
            )
        }
    )
)

Scaffold {
    OverlaySpinnerPreference(
        title = "多选选择器",
        entries = entries,
        collapseOnSelection = false
    )
}

监听展开状态

kotlin
var selectedIndex by remember { mutableStateOf(0) }
var expanded by remember { mutableStateOf(false) }
val options = listOf(
    DropdownItem(text = "选项 1"),
    DropdownItem(text = "选项 2"),
    DropdownItem(text = "选项 3"),
)

Scaffold {
    OverlaySpinnerPreference(
        title = "下拉选择器",
        summary = if (expanded) "展开" else "收起",
        items = options,
        selectedIndex = selectedIndex,
        onExpandedChange = { expanded = it },
        onSelectedIndexChange = { selectedIndex = it }
    )
}

属性

OverlaySpinnerPreference 属性(下拉列表模式)

属性名类型说明默认值是否必须
itemsList<DropdownItem>选项列表-
selectedIndexInt当前选中项的索引-
titleString选择器的标题-
modifierModifier应用于组件的修饰符Modifier
titleColorBasicComponentColors标题文本的颜色配置BasicComponentDefaults.titleColor()
summaryString?选择器的摘要说明null
summaryColorBasicComponentColors摘要文本的颜色配置BasicComponentDefaults.summaryColor()
spinnerColorsDropdownColors选择器的颜色配置DropdownDefaults.dropdownColors()
startAction@Composable (() -> Unit)?左侧显示的自定义内容null
bottomAction@Composable (() -> Unit)?底部显示的自定义内容null
insideMarginPaddingValues组件内部内容的边距BasicComponentDefaults.InsideMargin
maxHeightDp?下拉菜单的最大高度null
enabledBoolean组件是否可交互true
showValueBoolean是否显示当前选中的值true
renderInRootScaffoldBoolean是否在根(最外层)Scaffold 中渲染弹窗。为 true 时,弹窗覆盖全屏。为 false 时,在当前 Scaffold 的范围内渲染并进行位置补偿true
onExpandedChange((Boolean) -> Unit)?展开状态变化时的回调null
onSelectedIndexChange((Int) -> Unit)?选中项变化时的回调-

Entry 重载属性

属性名类型说明默认值是否必须
entryDropdownEntry单个下拉选项分组-
collapseOnSelectionBoolean选中后是否关闭弹出框true

Entries 分组重载属性

属性名类型说明默认值是否必须
entriesList<DropdownEntry>由分割线隔开的下拉选项分组-
collapseOnSelectionBoolean每次选中后是否关闭弹出框entries.size <= 1
renderInRootScaffoldBoolean是否在根 Scaffold 中渲染弹出框true

OverlaySpinnerPreference 属性(对话框模式)

属性名类型说明默认值是否必须
itemsList<DropdownItem>选项列表-
selectedIndexInt当前选中项的索引-
titleString选择器的标题-
dialogButtonStringString对话框底部按钮的文本-
modifierModifier应用于组件的修饰符Modifier
popupModifierModifier应用于弹出对话框的修饰符Modifier
titleColorBasicComponentColors标题文本的颜色配置BasicComponentDefaults.titleColor()
summaryString?选择器的摘要说明null
summaryColorBasicComponentColors摘要文本的颜色配置BasicComponentDefaults.summaryColor()
spinnerColorsDropdownColors选择器的颜色配置DropdownDefaults.dialogDropdownColors()
startAction@Composable (() -> Unit)?左侧显示的自定义内容null
bottomAction@Composable (() -> Unit)?底部显示的自定义内容null
insideMarginPaddingValues组件内部内容的边距BasicComponentDefaults.InsideMargin
enabledBoolean组件是否可交互true
showValueBoolean是否显示当前选中的值true
renderInRootScaffoldBoolean是否在根(最外层)Scaffold 中渲染对话框。为 true 时,对话框覆盖全屏。为 false 时,在当前 Scaffold 的范围内渲染true
onExpandedChange((Boolean) -> Unit)?展开状态变化时的回调null
onSelectedIndexChange((Int) -> Unit)?选中项变化时的回调-

对话框 Entry 重载属性

属性名类型说明默认值是否必须
entryDropdownEntry单个下拉选项分组-
dialogButtonStringString对话框底部按钮的文本-
collapseOnSelectionBoolean选中后是否关闭对话框true

对话框 Entries 分组重载属性

属性名类型说明默认值是否必须
entriesList<DropdownEntry>由分割线隔开的下拉选项分组-
dialogButtonStringString对话框底部按钮的文本-
collapseOnSelectionBoolean每次选中后是否关闭对话框entries.size <= 1
renderInRootScaffoldBoolean是否在根 Scaffold 中渲染对话框true
属性名类型说明默认值是否必须
itemsList<DropdownItem>此分组中显示的条目-
enabledBoolean此分组是否启用。为 false 时禁用整组条目;为 true 时仍会遵循每个条目的 enabled 状态true

分组标题预留给后续使用。原版 MIUI 下拉样式目前没有对应的分组标题表现,因此 title 字段暂不开放。

属性名类型说明默认值是否必须
textString选项显示的文本-
enabledBoolean选项是否可点击,禁用时置灰true
selectedBoolean选项是否处于选中状态false
onClick(() -> Unit)?点击选项时触发的回调null
icon@Composable ((Modifier) -> Unit)?显示在选项文本前的图标null
summaryString?显示在选项文本下方的摘要文本null
childrenList<DropdownItem>?可选的子菜单项;仅级联变体null
属性名类型说明
contentColorColor选项标题颜色
summaryColorColor选项摘要颜色
containerColorColor选项背景颜色
selectedContentColorColor选中项标题颜色
selectedSummaryColorColor选中项摘要颜色
selectedContainerColorColor选中项背景颜色
selectedIndicatorColorColor选中指示图标颜色

变更日志

基于 Apache-2.0 许可发布