Android 基础补强 B16|从 Material 控件到设计系统:颜色、反馈与可访问性
《第一行代码》第 12 章介绍 Toolbar、抽屉、悬浮按钮、Snackbar、卡片、刷新和折叠标题栏。学习这一章时,如果只记住控件名字,很容易做出每个页面都有按钮、整体交互却不一致的应用。
本篇从文章阅读客户端出发,理解这些组件背后的职责,再联系 Compose Material 3。它补充日课中的界面实践,不要求把书中的每一种控件都塞进 DevCommunity。
先按任务选择组件
顶栏表达当前位置和重要操作;卡片组织相关内容;Snackbar 提供短暂反馈及可选动作;抽屉适合特定导航结构;悬浮按钮通常强调一个主要动作。组件选择应服务于用户任务,而不是因为学到 FloatingActionButton 就强行加一个悬浮按钮。
对于阅读客户端,收藏可以直接放在文章操作区。若再增加一个含义相同的悬浮按钮,就需要解释两者关系。全局创建动作若不存在,空放一个加号只会制造疑问。练习中先回答每个控件解决哪个具体需求,再考虑视觉效果。
颜色是角色,不是到处复制常量
Material 3 以颜色、字体和形状等主题信息组织组件。页面应使用合适的语义角色表达内容与容器关系,而不是每个 Text 单独写一个颜色,切换深色模式时再逐处修补。Compose Material 3
以下示例在已有 Compose Material 3 工程里定义最小主题入口,使用组件默认配色。它需要 MaterialTheme、darkColorScheme、lightColorScheme、isSystemInDarkTheme 与 Composable;不包含品牌配色和持久化设置,未在此次写稿中编译。
kotlin
@Composable
fun ReaderTheme(
useDark: Boolean = isSystemInDarkTheme(),
content: @Composable () -> Unit
) {
MaterialTheme(
colorScheme = if (useDark) darkColorScheme() else lightColorScheme(),
content = content
)
}
D15 的主题偏好决定是否使用深色,主题入口负责提供对应视觉值,页面负责消费它们。这三个职责分开后,就不必让每张卡片自己读 DataStore。系统主题、用户选择和读取尚未完成的状态,也应有明确优先关系。
动态配色是否启用是另一项产品选择,支持条件需要按当前文档判断。即使使用动态配色,也应检查图片、网页和自定义绘制是否与主题一致,而不是假定所有内容都会被自动转换。
反馈要对应真实完成状态
点击收藏后立即显示"保存成功",但数据库随后写入失败,这会让反馈与事实不一致。可以明确采用等待成功后更新的策略,或者采用乐观更新并在失败时恢复和提示。选择哪一种都应能解释异常路径。
Snackbar 中的"撤销"也不是一句文案。它需要保留足够的信息恢复被撤销操作,并考虑操作期间又发生更新时怎样处理。例如取消收藏后撤销,要决定恢复原收藏时间还是重新计算,而不是随意插入一条内容缺失的记录。
同样,显示加载动画时应区分首次加载、带旧内容刷新和加载下一页。整个页面被遮住可能使用户无法阅读已有数据;只有底部追加失败时,不应误导用户认为全部内容都不存在。
看得见还不够,还要能理解和操作
图标按钮需要表达动作的可访问描述,例如"收藏文章"或"取消收藏",而不是机械朗读"星星"。装饰图不应该重复宣布相邻文字。已收藏状态不能只依靠颜色,还可以通过文案、图标形态和语义状态表达。Compose 可访问性
大字体时检查文本是否被固定高度裁切,触摸操作是否仍可到达,朗读顺序是否符合阅读路径。卡片整体可点击,同时内部又有收藏按钮时,要确认两个操作的语义与触摸区域不会互相干扰。
使用标准组件通常能获得合理默认行为,但自定义组合可能改变语义结构。不能因为采用了 MaterialTheme,就宣称所有可访问性需求已经自动满足。
从书中 View 组件迁移时保留问题意识
书中的 CoordinatorLayout、AppBarLayout 和折叠标题栏解决了特定的 View 布局与联动问题。迁移到 Compose 时,应重新选择对应结构与滚动行为,而不是只寻找名字相似的函数逐个替换。
先确认到底需要折叠标题还是只需要固定顶栏;是否有足够内容承受复杂动效;返回后滚动位置是否正确。这样才不会在状态和数据仍不稳定时,先引入一层难调试的滚动协调。
故障实验
把收藏成功提示放在真正写入之前,再让 Fake 存储返回失败。观察用户看到的文案是否与最后状态冲突,随后按选定策略修复。接着打开深色模式和大字体,检查图标、错误文本、禁用按钮以及对话反馈;最后用屏幕阅读辅助方式检查动作含义。
预期每一种反馈都有对应的真实状态,主题变化后仍可阅读,关键操作不依赖单一颜色。记录发现的是颜色问题、空间问题、语义问题还是业务时序问题,避免全部归为"UI 不好看"。
三道原创面试自测
Material Design 是否只是配色? 不是,也涉及组件职责、层级、反馈和交互一致性。追问"为什么不用某个控件",可以从项目任务出发解释,而不是只说自己不喜欢。
Snackbar 的撤销要注意什么? 必须有真实恢复逻辑和数据规则。追问"操作已经被后续更新覆盖怎么办",需要定义身份和版本条件,不允许无条件覆盖较新状态。
标准组件能否保证无障碍完成? 不能,组合方式、描述、字体适配与状态表达仍需检查。追问"怎么验收",用具体任务验证能否找到、理解和执行操作。
题库可对应主题与样式主题。完成本篇后,应能解释一处主题设计和一条反馈规则,而不是只展示换色截图。