鸿蒙新特性实战:@ohos.font — 系统字体管理、字形预览与自定义字体注册
引言
在移动应用界面设计中,字体是用户体验的第一触点。不同于 Web 前端的 CSS @font-face 即可加载网络字体,也不同于 iOS 的有限系统字体集,HarmonyOS NEXT 的 @ohos.font 模块提供了一套完整的字体管理 API——开发者可以枚举系统中安装的所有字体、查询任意字体的详细元数据(包括 weight、italic、monoSpace 等)、注册自定义 .ttf/.otf 文件供全局使用,甚至窥探系统 UI 字体配置的内部结构。
本文构建一个字体实验室 Demo,浏览系统字体列表并让每种字体以自身字形展示其名称,点击即可查看该字体的完整元数据(family/subfamily/postScriptName/weight/width/italic/monoSpace/symbolic),在实时预览区输入任意文字以选中的字体渲染,并演示通过 registerFont() 动态加载自定义 .ttf 文件。
读完本文,你将掌握:
- 字体枚举:
getSystemFontList()返回系统安装的所有字体名数组 - 字体详情查询:
getFontByName()返回FontInfo— 9 个字段的完整字体档案 - 字形预览:通过
fontFamily()属性将字体名作用于 Text 组件 - 自定义字体注册:
registerFont({ familyName, familySrc })动态加载外部字体文件 - UI 字体配置:
getUIFontConfig()暴露系统的 generic/alias/adjust/fallback 字体策略 - API 演进:部分 API 在 API 18 标记 deprecated,迁移到 UIContext.Font 的趋势
环境与权限
@ohos.font 属于 ArkUI 工具包,自 API 9 开始提供。导入方式:
import font from '@ohos.font';
零权限需求:字体查询和注册操作完全是客户端的行为,不涉及系统服务调用或用户数据访问,因此不需要任何权限声明。
一、核心数据类型
1.1 FontInfo — 字体元数据档案
interface FontInfo {
path: string; // 字体文件路径
postScriptName: string; // PostScript 名称(字体唯一标识)
fullName: string; // 完整字体名
family: string; // 字体系列名
subfamily: string; // 子系列名(如 Bold/Italic/Regular)
weight: number; // 字重(100=Thin ~ 900=Black)
width: number; // 字体宽度
italic: boolean; // 是否斜体
monoSpace: boolean; // 是否等宽字体
symbolic: boolean; // 是否支持符号字体
}
FontInfo 是最核心的数据结构——它完整描述了一个字体的"身份档案"。
postScriptName是字体的"身份证号",每个字体文件有且只有一个family+subfamily共同定位字体在族系中的位置weight遵循 CSS 字重规范,100(Thin)到 900(Black)italic标识是否斜体变体;monoSpace标识是否等宽;symbolic标识是否包含符号字形
1.2 FontOptions — 注册配置
interface FontOptions {
familyName: string | Resource; // 注册后的字体名
familySrc: string | Resource; // 字体文件路径
}
familyName 是注册后用于 Text().fontFamily() 的名称;familySrc 指向 .ttf 或 .otf 文件的沙箱路径。
1.3 UIFontConfig — 系统字体策略
interface UIFontConfig {
fontDir: Array<string>; // 系统字体文件目录
generic: Array<UIFontGenericInfo>; // 通用字体组配置
fallbackGroups: Array<UIFontFallbackGroupInfo>; // 回退字体策略
}
UIFontConfig 是 HarmonyOS 字体系统的"配置档案",暴露了系统如何组织通用字体(generic)和回退字体(fallback)的策略。这是理解 HarmonyOS 多语言排版能力的关键入口。
二、枚举系统字体列表
2.1 getSystemFontList()
let fontNames: string[] = font.getSystemFontList();
同步返回所有系统安装字体的名称数组。典型系统包含 50-100 款字体,涵盖中英文、日文、韩文等多个语言族系。
2.2 以字体本身展示字体名
最基本的"字体预览"就是把字体作用在自身名称上:
ForEach(fontNames, (name: string) => {
Text(name)
.fontFamily(name) // 精确匹配——该字体渲染自己的名字
.fontSize(16)
})
这个简单的技巧让用户能在列表中直观感受到每个字体的笔画风格。HarmonyOS Sans 系列字体会展示为现代无衬线风格,而宋体/楷体等中文字体会呈现出各自的经典造型。

三、查询字体详情
3.1 getFontByName()
let info: font.FontInfo = font.getFontByName('HarmonyOS Sans SC');
同步返回指定字体名的完整 FontInfo 对象。如果字体名不存在,该方法会抛出异常(需要 try/catch 包裹)。
3.2 字重解码
weight 字段的值与字重名称的对应关系:
| Weight 值 | 名称 | CSS 等价 |
|---|---|---|
| 100 | Thin | font-weight: 100 |
| 200 | ExtraLight | font-weight: 200 |
| 300 | Light | font-weight: 300 |
| 400 | Regular / Normal | font-weight: 400 |
| 500 | Medium | font-weight: 500 |
| 600 | SemiBold | font-weight: 600 |
| 700 | Bold | font-weight: 700 |
| 800 | ExtraBold | font-weight: 800 |
| 900 | Black | font-weight: 900 |
在 Demo 中,我们通过 weightLabel() 辅助函数将数值映射为人类可读的字重名称。
3.3 实战代码:获取并展示字体详情
let name = 'HarmonyOS Sans SC';
let info = font.getFontByName(name);
console.log('字体全名: ' + info.fullName);
console.log('PostScript 标识: ' + info.postScriptName);
console.log('字重: ' + info.weight + ' (Regular)');
console.log('是否等宽: ' + (info.monoSpace ? '是' : '否'));
console.log('是否斜体: ' + (info.italic ? '是' : '否'));
console.log('是否支持符号: ' + (info.symbolic ? '是' : '否'));
console.log('文件路径: ' + info.path);
四、自定义字体注册
4.1 registerFont()
try {
font.registerFont({
familyName: 'MyBrandFont',
familySrc: '/data/storage/el2/base/files/fonts/brand.ttf'
});
console.log('自定义字体注册成功');
} catch (e) {
console.error('注册失败: ' + JSON.stringify(e));
}
registerFont() 将外部 .ttf/.otf 字体文件加载到系统 FontManager 中。注册成功后,该字体可以通过 fontFamily('MyBrandFont') 在任何 Text 组件中使用,效果等同于系统自带字体。
注意事项:
familySrc路径必须是应用沙箱内的绝对路径(如/data/storage/el2/base/...)- 字体文件需要提前放入应用的沙箱存储中(通常通过
file.fs写入) - 注册是进程级的——应用退出后需要重新注册
- 该方法在 API 18 标记为
deprecated,推荐迁移到UIContext.Font#registerFont
4.2 注册后验证
// 注册后立即验证
let names = font.getSystemFontList();
if (names.indexOf('MyBrandFont') >= 0) {
console.log('字体已在系统列表中');
}
注册成功后,getSystemFontList() 的返回数组中会包含新注册的字体名。
五、系统 UI 字体配置
5.1 getUIFontConfig()
let config = font.getUIFontConfig();
console.log('字体目录: ' + config.fontDir.length + ' 个');
config.fontDir.forEach((dir, idx) => {
console.log(' [' + idx + '] ' + dir);
});
console.log('通用字体组: ' + config.generic.length + ' 组');
config.generic.forEach((gen) => {
console.log(' ' + gen.family + ' (别名: ' + gen.alias.length + ')');
});
console.log('回退字体组: ' + config.fallbackGroups.length + ' 组');
getUIFontConfig() 返回的是 HarmonyOS 字体系统的完整内部策略配置,包含三个核心维度:
- fontDir:系统从哪些目录加载字体文件(通常是
/system/fonts等系统路径) - generic:通用字体组——每组的
family定义了一个抽象字体系列(如 “sans-serif”),alias定义了不同字重的实际映射字体,adjust定义了字重映射规则 - fallbackGroups:回退策略——当渲染指定字体缺失的字形时,按
language+family匹配回退字体
这个 API 对于想深入理解 HarmonyOS 文本渲染管线的开发者来说是无价的。
六、Text.fontFamily() — 在 UI 中使用字体
获取字体名和详情的最终目的是在 UI 渲染中使用它们:
// 使用系统字体
Text('HarmonyOS 鸿蒙操作系统')
.fontFamily('HarmonyOS Sans SC')
.fontSize(28)
// 使用自定义注册字体
Text('Welcome to HarmonyOS')
.fontFamily('MyBrandFont')
.fontSize(24)
.fontWeight(FontWeight.Bold)
fontFamily() 属性接受字体名(family name)字符串。系统会优先使用指定字体渲染文本;如果该字体缺少某个字符的字形,会自动触发回退机制(根据 UIFontConfig.fallbackGroups 查找替代字体)。
七、API 演进趋势
从 API 版本注解中可以看出字体 API 的演进方向:
| API | 状态 | 新方向 |
|---|---|---|
font.registerFont() |
API 18 deprecated | UIContext.Font#registerFont |
font.getSystemFontList() |
API 18 deprecated | UIContext.Font#getSystemFontList |
font.getFontByName() |
API 18 deprecated | UIContext.Font#getFontByName |
HarmonyOS 正在将字体管理从全局单例模型迁移到 UIContext 上下文模型。这意味着未来的字体操作将按 UIWindow/UIAbility 上下文隔离——不同的 Ability 实例可以有不同的字体配置,而不共享全局状态。这对于多窗口应用、跨设备分布式场景来说是一个重要的架构升级。
八、实战 Demo:字体实验室
页面结构
字体实验室
├── 状态栏 — 已加载字体数量 + UIFontConfig 摘要
├── 字体预览区
│ ├── 可编辑样本文字输入框
│ ├── 字号调节(± 按钮,12-72px)
│ └── 大尺寸预览卡片(以选中字体渲染样本文字)
├── 字体详情面板(选中字体后显示)
│ ├── fullName + postScriptName
│ ├── family / subfamily / weight
│ ├── italic / monoSpace / symbolic 标签
│ └── 字体文件路径
├── 系统字体列表(50+ 款)
│ ├── 每种字体以自身字形展示其名称
│ ├── 字重标签(Thin/Regular/Bold 等)
│ └── 高亮选中项
├── 自定义字体注册
│ ├── 字体名 + 文件路径输入
│ └── 注册按钮 + 状态反馈
└── 核心 API 参考 — 10 个关键 API
4 个交互点
- 浏览系统字体列表 — 每种字体以自身字形展示其名称,右侧显示字重标签,点击选中高亮
- 实时字形预览 — 在顶部输入框编辑任意文字,选择字号(12-72),选中字体实时渲染用户输入的样本文字
- 字体详情查看 — 选中字体后展示完整的 FontInfo(9 个字段),含 family/subfamily/weight/italic/monoSpace/symbolic 标签
- 自定义字体注册 — 输入字体名和沙箱路径,点击"注册字体"将外部 .ttf 文件注册到系统,成功后刷新字体列表
核心代码位置
完整代码在 dev/entry/src/main/ets/pages/TypographyLabPage.ets(约 330 行),路由已注册为 pages/TypographyLabPage。
九、与 CSS @font-face 的对比
对于有 Web 开发经验的开发者:
| 维度 | CSS @font-face | HarmonyOS @ohos.font |
|---|---|---|
| 字体注册 | @font-face { font-family; src; } |
font.registerFont() |
| 字体枚举 | 无标准 API | font.getSystemFontList() |
| 字体元数据 | 无标准 API | font.getFontByName() — FontInfo |
| 字体策略查询 | 无 | font.getUIFontConfig() |
| 字形变体 | font-weight / font-style |
FontInfo.weight / .italic |
| 回退机制 | font-family: A, B, C |
UIFontConfig.fallbackGroups |
| 运行时动态加载 | Web Font Loader 库 | font.registerFont() 原生支持 |
HarmonyOS 的字体 API 远超 CSS 标准的能力范围——不仅提供了运行时注册,还提供了完整的字体元数据查询和系统策略检查。
十、总结
@ohos.font 是 HarmonyOS NEXT 字体系统的程序化入口,核心能力:
- 字体枚举:
getSystemFontList()返回系统全部字体名,通过fontFamily()即时预览 - 元数据查询:
getFontByName()提供 9 字段 FontInfo,覆盖字重/宽度/斜体/等宽/符号等所有维度 - 自定义字体:
registerFont()支持运行时加载外部字体文件,品牌定制化不再受限 - 策略洞察:
getUIFontConfig()暴露系统通用字体和回退策略的内部配置 - 演进趋势:API 18 起迁移到 UIContext 上下文模型,为多窗口场景铺路
结合 SymbolGlyph(系统图标)、RichEditor(富文本编辑器)和 Span(富文本排版),HarmonyOS 开发者已经掌握了从字体管理到排版渲染的完整工具链。
更多推荐



所有评论(0)