鸿蒙国际化 locale 感知排序 — UI 设计篇


一、设计目标
让用户一眼看出「不同排序规则下同一组数据顺序不同」,并理解 sensitivity、忽略标点、数字排序这些选项的实际效果。定位是排序规则对比台。
二、页面结构(组件树)
Scroll
└─ Column(宽 100%)
├─ Row:标题「国际通讯录」+ 📇
├─ Text:排序语言(小标题)
├─ Flex:5 种排序规则徽章(靛蓝选中 #4338CA)
├─ Text:排序结果(小标题)
├─ Column 白卡
│ ├─ Text:当前排序语言名(靛蓝小字)
│ └─ ForEach → 联系人行(序号 + 名字 + 语言徽标)
├─ Text:排序强度 sensitivity(小标题)
├─ Column 卡(浅靛蓝底 #EEF2FF)
│ ├─ Row:base/accent/case/variant 徽章
│ └─ ForEach → 排序结果(带序号)
└─ Text:忽略标点(小标题)
└─ Column 白卡
├─ Toggle 开关
└─ ForEach → O'Brien 系列排序结果
三、色彩与字号规范
主题色 #4338CA(靛蓝,象征"秩序/规则"),系列内第 6 个主题色:
| 元素 | 色值 | 字号 | 说明 |
|---|---|---|---|
| 页面标题 | #1F2937 | 22 Bold | |
| 联系人名 | #1F2937 | 14 | |
| 序号 | #9CA3AF | 12 | 灰色辅助 |
| 语言徽标 | 底 #EEF2FF / 字 #9CA3AF | 10 | 中英日韩标识 |
| 排序语言名 | #4338CA | 11 | |
| 选中徽章 | 底 #4338CA / 字白 | 11~12 |
主题色与"规则/秩序"语义绑定:靛蓝是权威、精确、可预期的颜色,正适合表达"排序是有规则可循的"——与 01 蓝(信息)、02 紫(时间)、03 青(钱)、04 橙(数据)、05 玫红(数量)形成完整色谱。
四、核心实现(UI 代码)
4.1 排序语言切换
5 种排序规则对应 5 种书写系统,点选即重排:
Flex({ wrap: FlexWrap.Wrap, justifyContent: FlexAlign.Start }) {
ForEach(['zh_CN', 'zh_TW', 'en_US', 'ja_JP', 'ko_KR'] as string[], (code: string) => {
Text(this.langLabel(code))
.fontSize(12).padding({ left: 10, right: 10, top: 6, bottom: 6 }).borderRadius(16)
.backgroundColor(this.currentLocale === code ? '#4338CA' : '#E5E7EB')
.fontColor(this.currentLocale === code ? Color.White : '#374151')
.onClick(() => { this.currentLocale = code; })
}, (code: string) => code)
}
.width('94%').margin({ top: 6 })
langLabel 把语言映射成排序规则名(拼音/注音/字母/假名/谚文),让用户理解"切语言 = 切排序规则"。
4.2 排序结果列表
排序结果实时反映当前 locale 规则,每行带序号和语言徽标:
ForEach(sortContacts(this.currentLocale), (c: Contact, idx: number) => {
Row() {
Text(`${idx + 1}.`).fontSize(12).fontColor('#9CA3AF').width('30')
Text(c.name).fontSize(14).fontColor('#1F2937').layoutWeight(1)
Text(c.lang).fontSize(10).fontColor('#9CA3AF')
.padding({ left: 6, right: 6, top: 2, bottom: 2 }).backgroundColor('#EEF2FF').borderRadius(6)
}.width('100%').padding({ top: 4, bottom: 4 })
}, (c: Contact, idx: number) => `${idx}-${c.name}`)
设计要点:
- 序号 + 名字 + 语言徽标三列:序号帮助对比位置变化,语言徽标(zh/en/ja/ko)让用户看到"谁往前、谁往后";
ForEachkey 用${idx}-${name}:排序变化时 key 变化触发重建,列表即时更新。
4.3 排序强度演示
sensitivity 四档徽章 + 结果列表:
Row({ space: 6 }) {
ForEach(this.sensNames(), (s: string, idx: number) => {
Text(s)
.fontSize(11).padding({ left: 8, right: 8, top: 4, bottom: 4 }).borderRadius(10)
.backgroundColor(this.sensIdx === idx ? '#4338CA' : '#E5E7EB')
.fontColor(this.sensIdx === idx ? Color.White : '#374151')
.onClick(() => { this.sensIdx = idx; })
}, (s: string) => s)
}.width('100%').justifyContent(FlexAlign.Start)
ForEach(this.sensSorted(), (s: string, idx: number) => {
Text(`${idx + 1}. ${s}`).fontSize(13).fontColor('#1F2937').width('100%').margin({ top: 4 })
}, (s: string, idx: number) => `${idx}-${s}`)
浅靛蓝底 #EEF2FF 与白色主列表区分——这是"专项演示区"。切到 base 时 café/cafe/CAFE 视为相同,结果顺序稳定;切到 variant 时全部区分。
4.4 忽略标点开关
Toggle({ type: ToggleType.Switch, isOn: this.ignorePunct })
.onChange((on: boolean) => { this.ignorePunct = on; })
.margin({ bottom: 6 })
ForEach(sortPunct(this.currentLocale, this.ignorePunct), (s: string, idx: number) => {
Text(`${idx + 1}. ${s}`).fontSize(13).fontColor('#1F2937').width('100%').margin({ top: 3 })
}, (s: string, idx: number) => `${idx}-${s}`)
开关打开时 O'Brien 与 Obrien 视为相同开头,都排在 O 组;关闭时撇号参与比较。这是"一个开关参数改变排序结果"的最直观演示——ignorePunctuation 是通讯录场景的默认推荐值,因为人名中的撇号/连字符不应影响分组位置。
五、多语言排版验证清单
| 检查项 | 方法 |
|---|---|
| 名字长度差异 | 联系人名 layoutWeight(1) 自适应 |
| 语言徽标不溢出 | 固定 10px 小字 + 圆角底 |
| 排序稳定性 | 相同名字(O’Brien 系列)顺序稳定 |
| 序号对齐 | 固定 width('30'),一位/两位数不错位 |
| 切换即时重排 | currentLocale 变化 → sortContacts() 重执行 |
五·五、交互细节
1. 切语言即重排
排序语言胶囊(拼音/注音/字母/假名/谚文)点击即改 currentLocale,sortContacts() 在渲染时重新执行,列表顺序即时变化。用户不需要任何刷新操作就能对比"同一份名单在两种规则下的差异"——这是本页最核心的交互。
2. 排序强度四档切换
sensIdx 四档(base/accent/case/variant)点击切换,下方样例列表(café/cafe/CAFE/Café/coffee)实时重排。切到 base 时前四个视为相同,顺序取决于原始数组稳定性;切到 variant 时全部区分——同一组数据四种顺序,对比一目了然。
3. 忽略标点开关
Toggle 开关直接控制 ignorePunctuation,O’Brien 系列(O’Brien/Obrien/O’Brien/OBrien)的排序结果实时变化。开关状态即时反馈,是"参数 → 结果"联动的最小闭环演示。
六、设计取舍
- 为什么靛蓝:系列第 6 色,排序/规则主题用靛蓝(秩序感);
- 为什么排序结果用白卡、专项演示用浅靛蓝卡:主列表与教学演示分区,避免混淆;
- 为什么加语言徽标:让用户看到"谁往前谁往后"——排序差异可视化;
- 为什么排序语言用平铺徽章:5 种规则,与系列一致。
六·五、可访问性
- 序号 + 名字 + 徽标三重信息:排序变化时即使用户看不清徽标,序号变化也能感知位置移动;
- 选中态双重编码:徽章用"靛蓝底白字"(颜色)+ 位置变化(结果列表重排)双重反馈;
- 字号对比:名字 14px 可读性优先,序号/徽标 10-12px 辅助信息不干扰主视觉;
- 开关状态可见:
Toggle自带开关语义,不依赖颜色判断开/关。
六·五、排序 UI 的交互细节
排序功能在 UI 层面有四个容易被忽视的细节:
排序结果的可见反馈:切换 locale 后列表顺序变化,如果只是静默重排,用户可能以为数据丢了——应配合"排序方式"标签(如"按拼音/按假名/按字母")与顺序变化的动效,让排序行为可感知。
搜索与排序的组合:搜索过滤(indexOf/includes)与排序(Collator)是两个独立操作——先过滤后排序,但过滤本身也要 locale 感知(德语的 ß 与 ss、中文的拼音首字母搜索),否则"搜不到"会出现在排序正确的列表里。
分组显示:通讯录按首字母分组(A/B/C…或あ/か/さ…)时,分组标题也要按 Collator 的顺序生成——英文 A B C、日文 あ か さ、中文拼音 A B C D…Z(或笔画)。分组的 key 由 Collator.compare 派生,不能硬编码 ASCII。
空态与降级:locale 数据缺失时 Collator 抛错,UI 兜底 String.prototype.localeCompare 或普通 sort()——但要提示"排序可能不精确",诚实降级。
七、小结
排序 UI 的核心是让规则差异可见:同一份名单,切语言顺序就变;同一组 café,切 sensitivity 顺序就变。徽章选择 + 结果列表 + 专项演示三区配合,把 Collator 的 4 个参数(locale/sensitivity/标点/数字)全部可视化,是技术演示应用的优秀范式。设计上坚持"数据一份、规则随 locale、UI 只展示差异"——用户看到的每一次顺序变化,都是 Collator 在背后按 ICU 规则表工作的直观证据。补充一条交互细节:排序方式切换后,最好在列表顶部保留"排序方式"小标签(如"按拼音")——用户滑动浏览时随时知道当前规则,避免"顺序怎么变了"的困惑;这也是 09 应用"把隐含规则显性化"设计模式在排序场景的复用——用户不需要成为语言学家,也能理解"顺序在随语言变化"。
设计收束:排序 UI 的黄金法则——规则差异可见、当前规则可查、降级诚实告知。
补一句:若列表同时支持搜索,排序标签旁应展示"过滤后 N 条",把过滤与排序两件事分开呈现,用户才不困惑。 排序体验的每一分打磨,都让"本地感"更真实一分。
更多推荐



所有评论(0)