外观
SectionRow / SectionItem — 分组标题与设置行
分组容器 + 一行设置项。省得每个页面各写一套字号和间距。
这两个名字互换过,别按旧文档写
旧的 SectionRows(复数,分组容器)现在是 SectionRow;旧的 SectionRow(单行)现在是 SectionItem。源码里已经没有 SectionRows 这个名字了。
基本用法
设置页分组(默认 GROUP 样式):
kotlin
SectionRow(
title = "账号",
modifier = Modifier.padding(horizontal = 16.dp),
) {
SectionItem(
icon = Phosphor.User,
title = "个人信息",
description = "邮箱、昵称和会员信息",
onClick = { openProfile() },
)
HorizontalDivider()
SectionItem(
icon = Phosphor.SignOut,
title = "退出登录",
description = "收藏与最近使用仍保留在本机",
danger = true,
showChevron = false,
onClick = { logout() },
)
}首页区块(SECTION 样式,带右侧动作):
kotlin
SectionRow(
title = "最近使用",
style = SectionHeaderStyle.SECTION,
actionText = "全部",
onActionClick = { openAll() },
modifier = Modifier.padding(horizontal = 16.dp),
) {
LazyRow { /* 横滑列表 */ }
}只要一根标题(内容是网格 / 需要自己管外边距时):
kotlin
SectionRow(title = "我的收藏", style = SectionHeaderStyle.SECTION) // content 不传
LazyVerticalGrid(columns = GridCells.Fixed(2)) { /* … */ }右侧换成自定义内容:
kotlin
SectionItem(
icon = Phosphor.Bell,
title = "通知",
description = "新作品上架时提醒我",
trailing = {
Box(modifier = Modifier.padding(end = 16.dp)) { // ★ 右内边距要自己给
Switch(checked = enabled, onCheckedChange = { enabled = it })
}
},
)参数
SectionRow
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
title | String | — | 分组标题 |
modifier | Modifier | Modifier | 修饰符。水平边距只能从这里给 |
style | SectionHeaderStyle | SectionHeaderStyle.GROUP | 标题样式 |
actionText | String? | null | 右侧动作文案。仅 SECTION 生效 |
onActionClick | (() -> Unit)? | null | 右侧动作点击。仅 SECTION 生效 |
content | (@Composable ColumnScope.() -> Unit)? | null | 分组内容。传 null 时只渲染标题行 |
SectionItem
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
icon | ImageVector | — | 左侧图标(裸线性图标,20dp) |
title | String | — | 标题,单行、超长省略 |
description | String | — | 说明文字,单行、超长省略。必传(不像 ListItem 的副标题可选) |
modifier | Modifier | Modifier | 修饰符 |
onClick | (() -> Unit)? | null | 传 null = 不可点 |
danger | Boolean | false | 标题与图标转 error 色(删除、退出这类) |
showChevron | Boolean | true | 是否显示右侧箭头。传了 trailing 就无效 |
trailing | (@Composable () -> Unit)? | null | 自定义右侧插槽,不带任何默认边距 |
SectionHeaderStyle
| 值 | 标题字阶 | 标题色 | 内容是否套卡片 | 用在哪 |
|---|---|---|---|---|
GROUP | labelMedium | onSurfaceVariant | 是 | 设置页分组 |
SECTION | titleLarge | onSurface | 否 | 首页区块 |
要点
actionText/onActionClick只在style = SECTION时生效。 两个都给才渲染右侧动作 —— 缺一个就什么都没有,不会画出半截控件。content = null时只渲染标题行,连卡片都不画。内容是网格、横滑列表这种自己管外边距的场景用的。- 水平边距全靠
modifier。 组件内部只有垂直方向的边距(GROUP标题下 8dp、卡片下 4dp),两个方向都没有水平内边距 —— 所以一定要传Modifier.padding(horizontal = 16.dp)之类的水平值,否则标题和卡片会贴着屏幕边。 danger只影响颜色,不影响点击行为。 危险项的确认逻辑得自己加(弹窗二次确认)。- 传了
trailing就跳过showChevron,而且右侧那 16dp 也不补。 源码里trailing和「箭头 + 16dp」是两条互斥分支 ——trailing分支里没有任何默认边距,所以自己在插槽内容外面包一层padding(end = 16.dp),否则它会贴到屏幕右边缘。 description必传(不是可空)。只想要一行标题的话用ListItem。SectionItem的可点区域是整行(含垂直 14dp 内边距),不需要自己再撑高。
说明
SectionRow的ColumnScope里可以用组件库的HorizontalDivider()在行之间划线 —— 全站统一这一个分割线规格。默认左右各缩进 16dp,正好和SectionItem的图标对齐。GROUP的卡片是clip(AppShapes.card)+background(surfaceContainer):卡片表面统一用surfaceContainer(浅色主题下是粉白),分组卡与内容卡同档,全页面卡片一个色。- 标题行在
SECTION下不留底部间距、在GROUP下留 8dp。首页区块的标题通常由调用方用一个 12dp 的下边距接管(见预览),而设置页分组的 8dp 是组件自己定的紧凑值。 - 组件内部边距固定、外部边距全归
modifier—— 这样同一套分组放进不同页面时不会因为「这个页面要窄一点」而出现两份间距逻辑。 - 和
ListItem的分工:SectionItem是分组内的一行 —— 裸线性图标、天然不需要背景(因为卡片由SectionRow提供)、行间靠HorizontalDivider分。ListItem是独立卡片式的一行 —— 自带 48dp 圆角图标容器、底色可配、右侧最多两个图标按钮。设置页那种「一整组卡片、行间细线」用这一对;散落在页面上的功能入口用ListItem。