android xml黑体字_如何在 Android 上使用思源黑体作为系统字体?

本文介绍了如何在 Android 5.x 及以上系统中使用思源黑体替换默认字体,提供详细步骤,包括字体文件复制、编辑 fonts.xml 文件、修复权限等,并探讨了字体字重在 UI 设计中的重要性,同时解决了一些常见问题和变砖风险,适合对 Android 系统有一定了解的用户操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

知道自己的答案和这篇答案撞车了,印象中知乎还有一篇写得相当详细的答案,但是我找不到了。我一直想把“如何评价思源黑体 (Source Han Sans) 字族?”过于冗长的部分独立出来,同时也想为自己折腾的历程做个总结,所以又写了这篇答案。

适用于 Android 5.x 以上,基于思源黑体 1.004 版本:

背景:

Google 已经将 Noto Sans CJK(思源黑体的 Google 版)作为 Android 5.0 以后的系统字体。(刚发布时,Adobe 说这是一款用于桌面的字体……[1])然而由于系统安装包的体积有限,Google 只在系统中内置了简、繁、日、韩 4 个高度子集化的字体,应该是只保留了相应地区与其他地区字形不同的字,日文假名依然使用 4.x 时代的 MTLmr3m.ttf(因为这 4 个字体都不含假名),而且只提供了一个字重。某些厂商(如 Motorola、Sony)更是将这些字体删除,仅使用古老的 Droid Sans Fallback。(索尼罪大滔天!)因此,要想获得 Android 5.x 的终极字体体验,还是需要折腾一番。

在操作之前,请先通读教程,手机要获得 Root 权限或者能进入 Recovery,需要掌握相应的 Android 和 Linux 知识。如果你不清楚每一步是在做什么和可能导致的后果,请不要操作。

先上效果

左:只使用 Regular,右:加入 Medium 与 Light

左:伪粗体,右:加入 Bold

(伪粗体会有较多的笔画粘连,边缘比较模糊,实机显示效果差别更大。)

1. 将需要的字体复制到 /system/fonts 目录下,我推荐 Region-specific Subset OTF 版,在这里可以获得。由于 Android 现在拥有了新的 OTF 渲染引擎,因此无需将 otf 改名 ttf,更不需要用字体编辑软件。比如(我没有韩文需求,所以这里没有列韩文版,下同):

SourceHanSansCN-Light.otf

SourceHanSansCN-Regular.otf

SourceHanSansCN-Medium.otf

SourceHanSansCN-Bold.otf

SourceHanSansTW-Light.otf

SourceHanSansTW-Regular.otf

SourceHanSansTW-Bold.otf

SourceHanSansJP-Light.otf

SourceHanSansJP-Regular.otf

SourceHanSansJP-Bold.otf一共增加了 61.3MB,比系统自带的 15.5 MB 要大不少。

注释:为什么要有 Medium?

按照 Google 官方 Material Design 指南 Styles 一节[2],Light 字重只用于最大的 Display 4 样式,而 Medium 广泛应用在小标题和按钮上,缺席的却是 Bold。可能是由于 Google 认为 Bold 对于 UI 字体来说太粗了,这一点在这一节的后半部分关于 Tall Script(南亚、东南亚语言)的解释中可以推测出来。

(Medium 字重和高亮色一起构成了“这个元素可以点击”这样的暗示。)

随着扁平化的潮流,iOS 的 UI 中 Medium 字重也广泛应用在标题上[3]:

(在系统 UI 中,你基本见不到 Bold 的身影。)

不幸的是,Android 发行版实际上只为 CJK 提供了一个字重,比 Tall Script 的两个字重还要少,Google 官方却厚颜无耻地说 Noto Sans CJK 有七种字重,所以可以和英文使用一样的字重设置……因此,当开发者使用 Medium 的时候,我们看到的是 Regular,而 Android 系统也不会像 Bold 那样自动加粗生成一个伪粗体,这种字体的微妙差别完全无法体现。

因此我的建议是为自己 UI 常用的语言备齐 4 个字重(Light、Regular、Medium、Bold),而对于其他的语言,备齐 3 个。这是因为在网页和文档中 Bold 还在广泛使用(为了做出强烈的对比),Light 也在一些网页设计中占有非常重要的地位(CSS 就提供 font-weight: lighter),甚至到了滥用的程度。

2. 编辑 /system/etc/fonts.xml,将(Android 5.x)

NotoSansHans-Regular.otf

NotoSansHant-Regular.otf

NotoSansJP-Regular.otf

NotoSansKR-Regular.otf

或者(Android 6.0)

NotoSansSC-Regular.otf

NotoSansTC-Regular.otf

NotoSansJP-Regular.otf

NotoSansKR-Regular.otf

替换为

SourceHanSansCN-Light.otf

SourceHanSansCN-Regular.otf

SourceHanSansCN-Medium.otf

SourceHanSansCN-Bold.otf

SourceHanSansTW-Light.otf

SourceHanSansTW-Regular.otf

SourceHanSansTW-Bold.otf

SourceHanSansJP-Light.otf

SourceHanSansJP-Regular.otf

SourceHanSansJP-Bold.otf

NotoSansKR-Regular.otf

理论上还应该修改为了兼容旧软件而保留的 /system/etc/fallback_fonts.xml,然而实际测试只修改 fonts.xml 没有发现有问题的地方,故此步骤可选,如有需要可以参照下方适用于 4.x 的部分。

3. 修复权限,将以上涉及的所有文件的权限设置为 644 (-rw-r--r--),可以用文件管理器手工操作,也可以使用 adb:

adb shell

su

mount -o rw,remount /system

chgrp 0 /system/etc/fonts.xml

chmod 644 /system/etc/fonts.xml

chgrp 0 /system/fonts/*

chmod 644 /system/fonts/*必须正确修改权限,否则可能会导致字体异常甚至变砖,请做好一切备份。即使按照正确的步骤操作,部分脆弱机型也可能会无限重启或变砖,为了保险可以在 Recovery 下操作。如遇上述情况可以尝试清理缓存和 Dalvik 缓存。(不要问我是怎么知道的,这些都是血与泪换来的。)

4. 重启。

附:Recovery 下全程用 adb 操作的步骤,Windows 系统

首先挂载 /system,然后:

for %i in (*.otf) do adb push %i /system/etc/%~nxi

for %i in (*.xml) do adb push %i /system/etc/%~nxi

adb shell

chmod 644 /system/etc/fonts.xml

chmod 644 /system/fonts/*

reboot

PS:随着 Android 字体技术的进步,缺字、错乱等问题都不复存在了,也不用再考虑 Android 4.x 中的粗体问题。

参考资料

[1] 隆重介绍 思源黑体:一款Pan-CJK 开源字体

[2] https://www.google.com/design/spec/style/typography.html

[3] https://developer.apple.com/library/ios/documentation/UserExperience/Conceptual/MobileHIG/ColorImagesText.html

-----

注意,在 Android 中修改字体,请务必注意权限问题,否则将导致字体异常甚至变砖。请做好一切备份,如果变砖请进入 Recovery 操作。

我习惯的做法不是替换字体,而是将字体直接复制到 /system/fonts 目录下,然后在 fallback_fonts.xml 的

DroidSansFallback.ttf

前加入

SourceHanSansCN-Regular.otf

SourceHanSansCN-Bold.otf

本来以为这么一做又入改字体的大坑了。但是这次 Android 奇怪的 fallback 机制居然表现得异常完美。

▲ fallback 韩文。

▲ 国际音标,依然那么销魂 惨不忍睹。(其实是 fallback 到了 Droid Sans Fallback。)

▲ 颜文字,完美。

(这一段主要是对我的这个答案的回应:对比 iOS 系统 Android 的字体渲染有何区别?)

(2) 进阶用法

我已经在 Android 上使用思源黑体半个多月,几乎没有任何兼容性上的问题,而且神奇地避开了 Android 在字体 fallback 和渲染上的一些小 bug [注1],更加坚定了我将其用作主力字体的信心。

Android

自 4.1 以来增加了 fallback 时对不同语言可以采用不同的次序的功能,配合 MTLmr3m.ttf

字体,为日语用户提供了日文汉字字形。于是思源黑体也可以如法炮制:将不同区域的版本拷贝到 /system/fonts 后,在原版的

fallback_fonts.xml 的

DroidSansFallback.ttf

前加入

SourceHanSansCN-Regular.otf

SourceHanSansCN-Bold.otf

SourceHanSansTWHK-Regular.otf

SourceHanSansTWHK-Bold.otf

SourceHanSansTWHK-Regular.otf

SourceHanSansTWHK-Bold.otf

SourceHanSansTWHK-Regular.otf

SourceHanSansTWHK-Bold.otf

再在之后加入

SourceHanSansJP-Regular.otf

SourceHanSansJP-Bold.otf

即可根据语言的不同自动调用相应的地区字形。(我没有安装韩文版。)

说几点问题:

从上面可以看出语言代码是区分大小写的。

只有日语能在切换系统界面语言时切换字形;语言设为繁体依然是简体字形,然而在网页中却可以。

系统语言设为日语时显示简体中文会缺字,无法正确 fallback。[注2]

繁体版的逗号太高了,明显高于居中的位置。

网页中有行距问题,参考下图:

(3) 粗体问题

这么做本来是没有问题的,但是万恶的 Adobe 把 1.001 版的粗体的信息除 Preferred Family

之外有关粗体的内容都改为了常规体(其实这是为了解决一些bug,比如[3])。加上 Android

奇怪的字体机制,发现一个常规体就会将它用作常规体(说好的严格按照 XML 顺序呢!),因此用 1.001 版的思源黑体直接按照上面的步骤操作完后会带来满屏粗体的情况。(感谢 @Shin li 、 @翟滢皓 、@黄俊 在原答案的评论)

所以我们要对它做一点小修改。首先去下载 Adobe OpenType 字体开发套件(AFDKO)。主要用到的是 ttx 工具。

首先,将 'head' 'OS/2' 和 'name' 表提取出来。

ttx -t "head" -t "OS/2" -t "name" SourceHanSansCN-Bold.otf

将 1.001 版和 1.000 版的表都提取出来后,用软件进行对比。把其中关于“Bold”(粗体)的内容都改好,把 fsType、fsSelection 和 macStyle 这几个 flag 也改过来。

或是按照下面的 diff 改(行号不一定相同)。

18c18

<

--->

30c30

<

--->

59c59

<

--->

84c84

< Regular

---> Bold

132c132

< Regular

---> Bold

177c177

< Regular

---> Bold

修改完毕后,将它们合并回原字体

ttx -m SourceHanSansCN-Bold.otf SourceHanSansCN-Bold.ttx

大功告成!接下来如法炮制繁体、日文等就可以了!全部修改完成后,按照(1)(2)中的步骤安装就可以了。

(4) 结论

综上,我可以毫不夸张地说这是我目前遇到的 Android 修改最方便的高质量中文字体。而且最重要的是没有那些“合成字体”的版权问题。

强烈推荐每一个对字体有要求的 Android 用户替换!注释

[注1] 其实在非网页环境下 fallback 是有一定问题的,比如知乎客户端的列表中,若涉及国际音标则无法显示,然而点开答案后音标正常,应该是答案界面使用了 WebView 所致。

[注2] 这是另一个问题,应该能通过安装 思源黑体 (Source Han Sans) 的各个版本有什么不同?

里提到的那个未正式发布的各地区字形)的全字数版本解决,不过这只是权宜之计,因为根本原因还是 Android 的 fallback

问题。(注:1.001 版已包括这个版本,OTF[不是Subset OTF]版即是。然而,它在 Android

上的兼容性竟远不如 Subset OTF版。)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值