react native for OpenHarmony iconfont 图标不显示问题

问题描述

在 OpenHarmony 5.0.0.71 上安装应用后,iconfont 图标完全不显示。困扰了我好几天!!

根本原因

在 HarmonyOS/OpenHarmony 中使用自定义字体(包括 IconFont),必须在 ArkTS 侧显式注册字体 。仅靠 font.json 配置文件是不够的,这是与 Android/iOS 最大的区别。

根据 Ant Design Mobile RN 官方文档(Badge 组件示例),字体必须通过以下两步配置:

  1. resources/base/profile/font.json 中声明字体
  2. Index.etsRNApp 配置中通过 fontResourceByFontFamily 显式注册

正确的修复方案

1. 字体文件位置

确保字体文件在正确位置:

复制代码
harmony/entry/src/main/resources/rawfile/iconfont.ttf

2. 创建字体配置文件

位置harmony/entry/src/main/resources/base/profile/font.json

内容

json 复制代码
{
  "font": [
    {
      "name": "iconfont",
      "file": "rawfile/iconfont.ttf"
    }
  ]
}

关键点

  • file 路径必须是 rawfile/iconfont.ttf(相对于 resources 目录)
  • name 字段必须与后续 React Native 中使用的 fontFamily 一致

3. 在 Index.ets 中注册字体(关键步骤)

位置harmony/entry/src/main/ets/pages/Index.ets

修改内容

typescript 复制代码
RNApp({
  rnInstanceConfig: {
    createRNPackages,
    enableNDKTextMeasuring: true,
    enableBackgroundExecutor: false,
    enableCAPIArchitecture: true,
    arkTsComponentNames: [],
    // ⚠️ 关键:必须显式注册字体资源
    fontResourceByFontFamily: {
      'iconfont': $rawfile("iconfont.ttf"),
    }
  },
  // ...其他配置
})

说明

  • fontResourceByFontFamily 是必需的,这是 HarmonyOS 加载自定义字体的核心机制
  • 键名 'iconfont' 必须与 font.json 中的 name 字段一致
  • $rawfile("iconfont.ttf") 直接引用 rawfile 目录下的文件

4. React Native 组件使用

IconFont.tsx

typescript 复制代码
const IconFont: React.FC<IconFontProps> = ({ name, size = 16, color = '#000', style }) => {
  const iconCode = IconFontMap[name];

  // fontFamily 必须与 font.json 和 Index.ets 中注册的名称完全一致
  const fontFamily = Platform.select({
    harmony: 'iconfont',
    android: 'iconfont',
    ios: 'iconfont',
    default: 'iconfont',
  });

  return (
    <Text
      style={[
        {
          fontFamily: fontFamily,
          fontSize: size,
          color: color,
          includeFontPadding: false,
          textAlignVertical: 'center',
        },
        style,
      ]}
      allowFontScaling={false}>
      {iconCode}
    </Text>
  );
};

最终目录结构

复制代码
harmony/entry/src/main/
├── ets/pages/
│   └── Index.ets  ✅ 在此注册 fontResourceByFontFamily
├── resources/
│   ├── base/profile/
│   │   └── font.json  ✅ 字体配置文件
│   └── rawfile/
│       └── iconfont.ttf  ✅ 字体文件

关键要点

  1. 双重配置机制

    • font.json:声明字体元数据
    • Index.ets 中的 fontResourceByFontFamily:实际加载字体资源
  2. 路径一致性

    • font.json 中:"file": "rawfile/iconfont.ttf"(相对路径)
    • Index.ets 中:$rawfile("iconfont.ttf")(直接引用)
  3. 名称一致性

    • font.json 中的 name
    • Index.etsfontResourceByFontFamily 的键名
    • React Native 组件中的 fontFamily
    • 三者必须完全一致
  4. 不需要手动调用 API

    • 不需要在 EntryAbility.ets 中使用 font.registerFont()
    • 不需要在 Index.ets 的 aboutToAppear 中手动注册
    • 通过 fontResourceByFontFamily 配置即可自动加载

常见错误

❌ 错误做法 1:只配置 font.json

json 复制代码
// 只有这个配置是不够的
{
  "font": [{"name": "iconfont", "file": "rawfile/iconfont.ttf"}]
}

❌ 错误做法 2:font.json 路径错误

json 复制代码
{
  "font": [
    {"name": "iconfont", "file": "font/iconfont.ttf"}  // ❌ 错误路径
  ]
}

❌ 错误做法 3:缺少 fontResourceByFontFamily

typescript 复制代码
RNApp({
  rnInstanceConfig: {
    createRNPackages,
    enableNDKTextMeasuring: true,
    // ❌ 缺少 fontResourceByFontFamily 配置
    arkTsComponentNames: []
  },
})

✅ 正确做法:双重配置

json 复制代码
// font.json
{
  "font": [{"name": "iconfont", "file": "rawfile/iconfont.ttf"}]
}
typescript 复制代码
// Index.ets
RNApp({
  rnInstanceConfig: {
    // ...
    fontResourceByFontFamily: {
      'iconfont': $rawfile("iconfont.ttf"),
    }
  },
})

测试步骤

bash 复制代码
# 1. 清理并重新构建
cd harmony
hvigorw clean
hvigorw assembleHap

# 2. 安装到设备并测试图标显示

参考资料

  1. Ant Design Mobile RN 官方文档

    • Badge 组件示例中的字体配置方法
    • 明确要求在 Index.ets 中使用 fontResourceByFontFamily 注册字体
  2. OpenHarmony 字体系统

    • font.json:声明性配置
    • fontResourceByFontFamily:实际资源绑定

版本信息

  • OpenHarmony: 5.0.0.71
  • React Native OpenHarmony: 0.72.5
  • Ant Design Mobile RN: 3.2.0

总结

核心原理:HarmonyOS 的字体加载采用"声明 + 注册"的双重机制,缺一不可。这与 Android/iOS 只需将字体文件放入指定目录即可使用的方式完全不同。理解这一点是解决问题的关键。

相关推荐
汉堡黄•᷄ࡇ•᷅1 小时前
鸿蒙开发: 案例集合List:ListItem侧滑(删除、收藏)
harmonyos·鸿蒙·鸿蒙系统
春卷同学1 小时前
拼图游戏 - Electron for 鸿蒙PC项目实战案例
javascript·electron·harmonyos
春卷同学1 小时前
基于 Electron 开发的跨平台鸿蒙PC端数字猜谜游戏桌面应用
游戏·electron·harmonyos
盐焗西兰花1 小时前
鸿蒙学习实战之路 - 轮播图组件实现
学习·华为·harmonyos
ChinaDragon2 小时前
HarmonyOS:转场动画
harmonyos
ChinaDragon2 小时前
HarmonyOS:转场动画-模态转场
harmonyos
不羁的木木2 小时前
【开源鸿蒙跨平台开发学习笔记】Day09:React Native 开发 OpenHarmony —— 仓库列表组件封装
笔记·学习·react native
青云交2 小时前
ShellCheck命令行工具适配开源鸿蒙PC实战指南
华为·开源·makefile·harmonyos·shellcheck·预编译二进制·hnp 打包
小简GoGo2 小时前
新手如何搭建配置Android Studio并成功运行React Native项目(使用自带的虚拟机运行)
react native·react.js·android studio