外观
状态视图 — LoadingState / ErrorState / EmptyHint
列表或页面的三种「没有正常内容」的状态:加载中、出错、空。
基本用法
三种状态一起用:
kotlin
when {
isLoading -> LoadingState(text = "加载中…")
error != null -> ErrorState(message = error, onRetry = { load() })
items.isEmpty() -> EmptyHint(text = "还没有收藏", description = "去挑几个喜欢的吧")
else -> Content(items)
}空态带一个「下一步去哪」的按钮:
kotlin
EmptyHint(
text = "收藏夹是空的",
description = "收藏之后会显示在这里",
actionText = "去逛逛",
onAction = { nav.navigate("home") },
)换图标 / 换配色:
kotlin
ErrorState(message = "没有网络", onRetry = { load() }, icon = Phosphor.WifiSlash)
EmptyHint(
text = "什么都没有",
actionText = "刷新",
onAction = { load() },
colors = EmptyHintDefaults.colors(
iconContainerColor = MaterialTheme.colorScheme.errorContainer,
),
)参数
LoadingState
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
modifier | Modifier | Modifier | 修饰符。内部会 fillMaxSize() |
text | String? | null | 指示器下方文案,不传就不显示 |
ErrorState
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
message | String | — | 错误说明,居中显示 |
onRetry | () -> Unit | — | 「重新加载」按钮回调 |
modifier | Modifier | Modifier | 修饰符 |
icon | ImageVector | Phosphor.CloudSlash | 图标 |
EmptyHint
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
text | String | — | 主文案 |
modifier | Modifier | Modifier | 修饰符 |
description | String? | null | 说明文案,空白等同于不传 |
icon | ImageVector | Phosphor.Tray | 图标 |
actionText | String? | null | 行动按钮文案。必须和 onAction 同时给才渲染 |
onAction | (() -> Unit)? | null | 行动按钮回调 |
colors | EmptyHintColors | EmptyHintDefaults.colors() | 配色 |
EmptyHintColors
| 字段 | 默认值 |
|---|---|
iconContainerColor | MaterialTheme.colorScheme.surfaceContainerHighest |
iconColor | MaterialTheme.colorScheme.onSurfaceVariant @ 70% |
textColor | MaterialTheme.colorScheme.onSurface |
descriptionColor | MaterialTheme.colorScheme.onSurfaceVariant |
要点
- 行动按钮必须文案和回调同时给。 判断条件是
actionText != null && onAction != null,只给一个不会渲染 —— 防呆,避免画出一个点了没反应的按钮。 - 三个都自带
fillMaxSize(),直接塞进when分支即可,不用自己再包居中容器。ErrorState/EmptyHint还自带 24dp 内边距。 ErrorState的按钮文案固定是「重新加载」,不可配。 要别的文案自己拼一套。- 空态尽量给「下一步去哪」。 只告诉用户「这里没有东西」价值很低;给一个「去逛逛」比什么都强 —— 所以行动按钮是
EmptyHint上的可选参数,而不是另一个组件。 - 别用空态代替错误态。 用户会理解成「没有数据」而不是「加载失败」,然后反复下拉重试。语义不同就换组件。
说明
- 只有一份实现。 图标尺寸、间距、字阶都在私有的内容函数里,行动按钮只是多画一行 —— 所以「带按钮的空态」和「普通空态」的尺寸永远一致。
- 视觉规格:图标容器 72dp +
AppShapes.iconContainerLarge+surfaceContainerHighest底;图标 32dp;图标与文案间距 16dp;主文案与说明间距 6dp;文案与按钮间距 20dp。 - 主文案用
titleSmall、说明用bodySmall:空态的主文案是一句「结论」,该比说明重一档。 LoadingState用LoadingIndicator的Medium档,并把颜色显式传成primary(而不是靠默认配色)。整页加载用中档比小档更有存在感。- 三者的分工:
LoadingState= 正在来;ErrorState= 没来成、可以重试;EmptyHint= 本来就该是空的。