HarmonyOS 鸿蒙Next 自定义字体无法全局使用如何处理
HarmonyOS 鸿蒙Next 自定义字体无法全局使用如何处理
【问题现象】
registerFont注册全局生效的自定义字体失败,只能注册页面级字体。
1. 预期效果
注册自定义字体后,在应用中能成功使用该字体。
2. 实际效果
注册自定义字体后,显示效果与默认字体相同。
问题代码如下:
注册字体
// 注册iconFont font.registerFont({ familyName: 'iconFont', // 自定义字体存储在rawfile的font文件夹下 familySrc: $rawfile('font/STXINGKA.TTF') })
使用字体
[@Component](/user/Component) [@Entry](/user/Entry) struct Index { build() { Column() { // 使用自定义字体的文字 Text("图标字体") .fontSize(30) .fontFamily("iconfont") // 使用默认字体的文字 Text("图标字体") .fontSize(30) }.width('100%') } }
【背景知识】
可参考官方文档@ohos.font (注册自定义字体)。
【定位思路】
定位自定义字体无法使用的原因,需要从注册字体信息是否正确、使用时生命周期是否有效等方面来检查。常见的定位方式有如下两种:
1. 注册信息填写不正确。
请根据接口文档font.registerFont进行检查。
2. 注册生命周期不正确。
当自定义字体注册信息填写正确,但仍然无法使用时,是因为全局使用自定义字体,需在EntryAbility.ets文件的onWindowStageCreate生命周期中,通过windowStage.loadContent回调来注册。
详情参考windowStage.loadContent回调方法。
【解决方案】
根据定位思路可以做出如下操作:
1. 检查注册信息
首先请检查注册信息填写是否有误。
自定义字体被放在了rawfile的font文件夹下,注册路径正确无误,如下图所示:
2. 检查生命周期
根据定位思路,其次检查全局定义的字体生命周期是否正确。
代码示例如下:
//在entryability.ets的onWindowStageCreate中,通过windowStage.loadContent回调注册自定义字体
onWindowStageCreate(windowStage: window.WindowStage): void {
windowStage.loadContent('pages/Index', (err, data) => {
windowStage.getMainWindow().then(res => {
// 注册全局生效的自定义字体
const uiCtc = res.getUIContext()
uiCtc.getFont().registerFont({
familyName: 'iconfont',
// STXINGKA.TTF保存在rawfile目录下
familySrc: $rawfile("font/STXINGKA.TTF")
})
})
if (err.code) {
hilog.error(0x0000, 'testTag', 'Failed to load the content. Cause: %{public}s', JSON.stringify(err) ?? '');
return;
}
hilog.info(0x0000, 'testTag', 'Succeeded in loading the content. Data: %{public}s', JSON.stringify(data) ?? '');
});
}
//在Index.ets中,通过Text组件使用注册后的字体
@Component
@Entry
struct Index {
build() {
Column() {
// 使用自定义字体的文字
Text("图标字体")
.fontSize(30)
.fontFamily("iconfont")
Blank()
// 使用默认字体的文字
Text("图标字体")
.fontSize(30)
}.width('100%')
}
}
处理效果:
如图所示,自定义字体已生效。
其他注意事项:
- 字体文件需要下载到本地使用,并且unicode编码要获取正确。
- 编译时需要在真机/模拟器上调试,预览器上不能正常展示。
【总结】
@ohos.font可以注册出页面级的字体,也可以注册出全局性的字体,全局字体需要通过windowStage.loadContent进行回调注册。