鸿蒙应用如何接入第三方字体?
适用范围
本文适用于使用 ArkTS 和 ArkUI 开发的 HarmonyOS 应用,说明如何将 .ttf 或 .otf 字体文件放入工程、完成字体注册,并在 Text 等组件中使用
较早的项目可能使用 @ohos.font 中的静态 registerFont() 方法,该方法在较新的 API 中已经废弃,新代码应优先使用 UIContext 提供的字体管理接口
准备字体文件
第三方字体通常以 .ttf 或 .otf 文件提供,HarmonyOS 工程可以同时存放多个字体文件
使用字体前需要确认以下事项
- 字体授权允许嵌入应用并随安装包分发
- 中文字体文件通常较大,需要关注 HAP 安装包体积
- 文件名建议只使用英文字母、数字、连字符和下划线
放置字体文件
在模块的 resources/rawfile 目录下创建 fonts 目录,并将字体文件放入其中
entry/src/main/resources/rawfile/fonts/SourceHanSerifSC-Regular.otf
字体授权文件 ( license / OFL ) 建议与字体一起保留,但授权文件不参与字体注册
定义字体名称常量
建议将应用使用的字体名称集中定义,避免在多个页面中重复填写字符串
在以下位置创建字体配置文件
entry/src/main/ets/common/AppFonts.ets
写入
export const APP_SERIF_FONT_FAMILY: string = 'xxSourceHanSerif';
这里的 xxSourceHanSerif 是应用内部使用的字体别名,可以自行命名
该名称不必与字体文件名完全一致,但注册字体和使用字体时必须保持一致
注册字体
字体文件放入工程后不能直接通过 .fontFamily() 使用,必须先在 UI 上下文中完成注册
可以在应用入口页面的 aboutToAppear() 生命周期中注册,例如
import { hilog } from '@kit.PerformanceAnalysisKit';
import { APP_SERIF_FONT_FAMILY } from '../common/AppFonts';
@Entry
@Component
struct Index {
aboutToAppear(): void {
try {
this.getUIContext().getFont().registerFont({
familyName: APP_SERIF_FONT_FAMILY,
familySrc: $rawfile('fonts/SourceHanSerifSC-Regular.otf')
});
} catch (error) {
hilog.error(
0x0000,
'HomePage',
'Register app font failed: %{public}s',
JSON.stringify(error)
);
}
}
build() {
Column() {
Text('应用首页')
}
}
}
familyName
字体在应用中的注册名称,后续 .fontFamily() 必须使用同一个名称
familySrc
字体文件资源,使用 $rawfile() 进行链接
$rawfile('fonts/SourceHanSerifSC-Regular.otf')
注册时机
应在首次渲染使用该字体的组件之前完成注册
单 UIAbility、单主窗口应用通常可以在入口页面注册一次,不应在每个普通组件中重复注册
如果应用包含多个 UIAbility、多个窗口或彼此独立的 UIContext,需要在相应 UIContext 中分别确认字体已经注册
在组件中使用字体
先导入字体名称常量
import { APP_SERIF_FONT_FAMILY } from '../common/AppFonts';
然后通过 .fontFamily() 应用字体
Text('瓷序')
.fontSize(30)
.fontFamily(APP_SERIF_FONT_FAMILY)
.fontColor('#D8A756')
只需要对部分文字使用第三方字体时,给对应的 Text 组件设置 .fontFamily() 即可
Column({ space: 12 }) {
Text('使用第三方字体的标题')
.fontFamily(APP_SERIF_FONT_FAMILY)
.fontSize(28)
Text('继续使用系统默认字体的正文')
.fontSize(16)
}
注册多个字体文件
fonts 目录中可以放置多个 .otf 或 .ttf 文件,每个需要使用的字体文件都应单独注册
例如
entry/src/main/resources/rawfile/fonts/
├─ SourceHanSerifSC-Regular.otf
├─ SourceHanSerifSC-Medium.otf
└─ SourceHanSansSC-Regular.otf
可以先定义多个字体名称
export const APP_SERIF_REGULAR: string = 'xxSerifRegular';
export const APP_SERIF_MEDIUM: string = 'xxSerifMedium';
export const APP_SANS_REGULAR: string = 'xxSansRegular';
再分别注册
const fontManager = this.getUIContext().getFont();
fontManager.registerFont({
familyName: APP_SERIF_REGULAR,
familySrc: $rawfile('fonts/SourceHanSerifSC-Regular.otf')
});
fontManager.registerFont({
familyName: APP_SERIF_MEDIUM,
familySrc: $rawfile('fonts/SourceHanSerifSC-Medium.otf')
});
fontManager.registerFont({
familyName: APP_SANS_REGULAR,
familySrc: $rawfile('fonts/SourceHanSansSC-Regular.otf')
});
使用时选择对应的字体名称
Text('中等字重标题')
.fontFamily(APP_SERIF_MEDIUM)
.fontSize(24)
Text('无衬线正文')
.fontFamily(APP_SANS_REGULAR)
.fontSize(16)
推荐的工程组织方式
字体文件、字体名称和字体使用代码建议分别承担不同职责
entry/src/main/resources/rawfile/fonts/
存放字体文件和授权文件
entry/src/main/ets/common/AppFonts.ets
定义字体名称常量
entry/src/main/ets/pages/Index.ets
在入口页面注册字体
entry/src/main/ets/components/
entry/src/main/ets/pages/
在具体组件和页面中通过 .fontFamily() 使用字体
完整链接关系
字体从文件到界面生效的关系如下
字体文件
entry/src/main/resources/rawfile/fonts/SourceHanSerifSC-Regular.otf
│
│ $rawfile('fonts/SourceHanSerifSC-Regular.otf')
▼
registerFont({ familyName, familySrc })
│
│ familyName: 'xxSourceHanSerif'
▼
APP_SERIF_FONT_FAMILY
│
│ .fontFamily(APP_SERIF_FONT_FAMILY)
▼
Text 等 ArkUI 组件
常见问题
粗体效果不符合预期
不要只依赖系统模拟粗体,将对应的 Medium、Semibold 或 Bold 字体文件单独注册并使用
应用安装包明显变大
中文字体可能包含大量字符,应只保留项目确实需要的字体和字重,并在字体授权允许的前提下考虑使用官方子集版本
字体文件可以放多个吗
可以,同一个 fonts 目录能够存放多个 .otf 和 .ttf 文件,但每个实际使用的文件都需要注册

所有评论(0)