Skip to content

状态视图 — 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 ​

参数类型默认值说明
modifierModifierModifier修饰符。内部会 fillMaxSize()
textString?null指示器下方文案,不传就不显示

ErrorState ​

参数类型默认值说明
messageString—错误说明,居中显示
onRetry() -> Unit—「重新加载」按钮回调
modifierModifierModifier修饰符
iconImageVectorPhosphor.CloudSlash图标

EmptyHint ​

参数类型默认值说明
textString—主文案
modifierModifierModifier修饰符
descriptionString?null说明文案,空白等同于不传
iconImageVectorPhosphor.Tray图标
actionTextString?null行动按钮文案。必须和 onAction 同时给才渲染
onAction(() -> Unit)?null行动按钮回调
colorsEmptyHintColorsEmptyHintDefaults.colors()配色

EmptyHintColors ​

字段默认值
iconContainerColorMaterialTheme.colorScheme.surfaceContainerHighest
iconColorMaterialTheme.colorScheme.onSurfaceVariant @ 70%
textColorMaterialTheme.colorScheme.onSurface
descriptionColorMaterialTheme.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 = 本来就该是空的。