一屏界面同时在回答三个问题
上一章讲的是「每个数要有出处」。这一章讲更前面的一步:这个元素为什么在这儿。界面上的每一样东西都在回答三个问题之一,答不上来的那些,占的每一寸空间都是净亏损。
用户站在你的界面前,脑子里有三个问题
不管什么 App、什么页面,一个人打开它的头两秒,脑子里跑的是同样三句话:
界面上每一个可见的东西,都应该在回答其中某一个。这句话有两个用法,而且都很实用:
- 找空缺——某一问一个元素都没回答。「我能做什么」空着 = 死界面;「现在怎么了」空着 = 用户点完不知道成没成。
- 找抢答——同一问被太多元素抢着回答。三个元素都在争「这一屏最重要的动作」,用户就会愣住。
拆一屏给你看
拿一个再普通不过的「订单详情」页,把上面每个元素标一下它在答哪一问:
注意最后一行那张装饰插画。
它不难看。设计上它甚至可能是这一屏里最精致的东西。但它一个问题都没回答——它不告诉你这是什么,不给你任何可做的事,也不报告任何状态。
一个元素如果三问都答不上,它就该被删掉。
注意这条规则的形式:它不需要你判断好不好看,只需要你回答一个是非题。这就是把设计问题变成工程问题的样子——可以在 code review 里问出口的问题。
唯一的例外是「呼吸」:纯粹的留白确实不答任何问题,但它的作用是让其他元素答得更清楚(第 5 章)。留白和装饰的区别在于:留白是空的,装饰是满的。
三问对应三套完全不同的手法
这三问最有价值的地方,是它们各自有一套不该混用的表达方式。
① 这是什么 —— 靠层级
回答「这是什么」的东西(标题、名称、正文、图片),靠的是大小和轻重。它们之间的关系是「谁包含谁」「谁是主谁是次」,所以用字号、字重、留白来分层——这是卷 III 的内容。
这类元素不该有颜色。一个标题染成蓝色,用户会以为它能点。
② 我能做什么 —— 靠可供性
回答「我能做什么」的东西(按钮、链接、输入框、开关),靠的是看起来能操作:有边界、有色彩、有按下的反馈。
「扁平化」被误解得最惨的地方就是这里。扁平化去掉的是拟物的材质,不是可操作的信号。一个没有边框、没有背景、只是颜色深一点的文字,用户不知道它能点。
可查的判据:把界面转成灰度,可点的东西还能不能一眼认出来?如果只靠颜色区分,那对色觉障碍者和所有在阳光下看屏幕的人来说,它就是不能点的。
③ 现在怎么了 —— 靠对比与位置
回答「现在怎么了」的东西(状态标签、进度、报错、加载、空态),特点是它平时不在。它是变化的,是临时的,是需要被注意到的。
所以它靠的是和周围拉开对比,以及出现在正确的位置——报错必须紧挨着出错的那个输入框,而不是屏幕顶上飘一个 Toast。
因为写代码的时候它不在。你调试的永远是「正常」那一条路径:数据加载好了,网络是通的,列表不是空的。
于是加载态是个默认的转圈,空态是一片白,错误态是一句 Something went wrong。这三个界面,用户见到的频率比你想的高得多——而它们恰恰是用户最焦虑的时刻。
第 20 章会把这件事变成一张能数格子的表。
推论:标签是最后手段
三问最实用的一个副产品,是它能帮你删掉一半的文字。
看这三行:
邮箱: hello@example.com 电话: 138 0000 0000 状态: 已发货
左边那三个标签在答哪一问?名义上是「这是什么」。但真的需要吗——hello@example.com 这个东西,长着一个 @,用户会不知道它是邮箱吗?
先问一句:值本身能不能自己说清楚?能的话,标签就是纯粹的噪音——它占了一列宽度、多了一次视觉停顿,换来零信息。
三种由重到轻的处理:
- 直接删——邮箱、电话、网址、金额、日期,格式本身就是身份。
- 合并进值里——「已发货」比「状态:已发货」好;「共 12 件」比「数量:12」好。
- 留着但压轻——真的会歧义时(
2026-08-04是下单还是发货?),保留标签,但把它做成第 12 章说的「次要层级」:更小、更淡,绝不和值一样重。
最糟的写法是标签和值一样大一样黑——那等于说「标签和内容同等重要」,而它显然不是。
删完之后那三行变成:
hello@example.com 138 0000 0000 已发货
元素少了三个,信息一点没丢,而且扫读速度快了一倍——因为眼睛不用每行先跳过一个标签。
三问失衡的三种典型病
| 症状 | 三问上的样子 | 用户的感受 |
|---|---|---|
| 死界面 | 「我能做什么」为 0 | 看完了,然后呢?——常见于「详情页」和「结果页」 |
| 抢答 | 「我能做什么」有 3 个同等重量的 | 不知道该点哪个,于是一个都不点 |
| 失联 | 「现在怎么了」为 0 | 点完不知道成没成,于是又点一次 |
| 噪音 | 有元素三问都不答 | 说不出哪里不对,就是觉得挤、觉得花 |
「抢答」值得多说一句,因为它最反直觉。
你以为把三个按钮都做成主按钮是「都很重要」,但用户读到的是「你自己也不知道我该干嘛」。一屏只能有一个主动作。其余的必须在视觉上明确降级——降级的手段是第 12 章的内容,但规则现在就能记住:降级不是把它做小做丑,是把它做轻。
Compose 里,这三问其实已经有对应的组件族了。用对组件,一半的问题自动消失:
// ① 这是什么 —— 只有排版,没有交互,没有颜色
Text(style = MaterialTheme.typography.headlineSmall)
Text(style = MaterialTheme.typography.bodyMedium)
// ② 我能做什么 —— 一屏一个 Filled,其余降级
Button(onClick = ...) // filled:主动作,一屏一个
OutlinedButton(onClick = ...) // 次动作
TextButton(onClick = ...) // 更次要
IconButton(onClick = ...) // 自带 48dp 触摸目标(第 19 章)
// ③ 现在怎么了 —— 状态有自己的组件,别用 Text 硬凑
AssistChip / FilterChip // 状态标签
LinearProgressIndicator // 进度
Snackbar // 临时反馈
supportingText = { Text(error) } // 报错:挂在出错的那个字段上
一条很省事的经验:当你发现自己在用 Text + Modifier.clickable 造按钮时,停一下。你八成正在把「这是什么」和「我能做什么」混成一个东西——顺带还丢了触摸目标和按下反馈。
这一问怎么用
实际用法很轻:界面写完,从上往下扫一遍,每个元素问一句「你答哪一问」。
答不上来的删掉。同一问抢答的,留一个,其余降级。整屏缺某一问的,补上。
这个动作花不了两分钟,而它抓到的问题,通常比你调半小时颜色抓到的多。
- 「这个元素要不要留」——三问都答不上就删,不再靠感觉权衡。
- 「这一屏几个主按钮」——永远是一个。其余降级,不再每次纠结。
- 「标题要不要染个色」——不要。颜色是「能做什么」和「现在怎么了」的信号,不是层级的手段。