HarmonyOS 鸿蒙Next中自定义字体无效

HarmonyOS 鸿蒙Next中自定义字体无效 在EntryAbility.ets的onWindowStageCreate里

windowStage.loadContent('pages/test2', (err) => {
  font.registerFont({
    familyName:'mf1',
    familySrc:($r('app.media.SIMYOU'))//这个是幼圆,也试过下载的其他字体也不行
  })

在test2界面

aboutToAppear() {
  try {

    // 注册字体
    font.registerFont({
      familyName: 'mf1',
      // familySrc: $rawfile('fonts/SIMYOU.ttf')  // 也试过不行
      familySrc:($r('app.media.SIMYOU'))
    });
    console.log('字体注册成功');
  } catch (error) {
    console.error('字体注册失败:', error);
  }
  // 检查字体是否可用
  setTimeout(() => {
    const fontList:string[] = font.getSystemFontList();
    console.log('可用字体列表:', JSON.stringify(fontList));

    // 检查是否包含我们的字体
    if (fontList.includes('mf1')) {
      console.log('mf1 字体加载成功');
    } else {
      console.log('mf1 字体未找到,使用备用字体');
    }
  }, 500);
}
Text('测试字体')
  .fontSize(30)
  .fontColor('#FFFFFF')
  .fontFamily('mf1')

字体文件放到项目的

src/main/resources/base/media/SIMYOU.TTF

src/main/resources/rawfile/fonts/SIMYOU.TTF

src/main/ets/fonts/SIMYOU.TTF

这三个目录都试过都不行是怎么回事


更多关于HarmonyOS 鸿蒙Next中自定义字体无效的实战教程也可以访问 https://www.itying.com/category-93-b0.html

6 回复

楼主您好,我这边测试幼圆是可以正常加载出来的且可以注册成功,这边看您检测的api是getSystemFontList,该接口仅在PC/2in1设备上生效,建议您检测一下自己的使用设备是否符合。推荐使用getSystemFontFullNamesByType接口获取系统最新支持的字体列表数据。我这边测试是注册成功了,您可以看下:

import {  Font } from '@kit.ArkUI';
import { text } from '@kit.ArkGraphics2D';
import { BusinessError } from '@kit.BasicServicesKit'

@Entry
@Component
struct shareTestComponent {
  @State message: string = 'Hello World';

  aboutToAppear() {
    let font: Font = this.getUIContext().getFont()
    try {

      // 注册字体
      font.registerFont({
        familyName: 'mf1',
        // familySrc: $rawfile('fonts/SIMYOU.ttf')  // 也试过不行
        familySrc: $rawfile('SIMYOU.TTF')
      });
      console.log('字体注册成功');
    } catch (error) {
      console.error('字体注册失败:', error);
    }
  }

  build() {
    Column() {
      Text('幼圆')
        .align(Alignment.Center)
        .fontSize(50)
        .fontColor(Color.Blue)
        .fontFamily('mf1')
        .onClick(() => {
          let fontType:text.SystemFontType = text.SystemFontType.CUSTOMIZED;
          let promise = text.getSystemFontFullNamesByType(fontType)
          promise.then((data) => {
            console.info(`then font list size: ${data.length}`)
            data.forEach((fontItem) => {
              console.info(fontItem)
            })
          }).catch((error: BusinessError) => {
            console.error(`Failed to get font fullNames by type, error: ${JSON.stringify(error)}`);
          });
        }) // 使用幼圆字体
    }
    .width('100%')
    .margin({ top: 30 })
  }
}

【背景知识】

自定义字体是指开发者根据应用需求创建或选择的字体,通常用于实现特定的文字风格或满足独特的设计要求。当应用需要使用特定的文本样式和字符集时,可以注册并使用自定义字体进行文本渲染。

实现流程:

  • 注册自定义字体:将字体文件(如ttf、otf文件等)从应用资源注册到系统中,使得应用能够使用这些字体进行文本渲染。注册过程通常指将字体文件通过字体管理接口注册到系统字体库中,以便在应用中进行调用。
  • 使用自定义字体:在应用中显式指定使用已注册的自定义字体进行文本渲染。开发者可以根据需要选择特定的文本样式(如常规、粗体、斜体等),并将其应用到UI元素、文本控件或其他文本展示区域,以确保符合设计要求并提供一致的视觉效果。

更多关于HarmonyOS 鸿蒙Next中自定义字体无效的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


1、getSystemFontList仅在PC/2in1设备上生效;

2、我这边是可以生效的:试一下下面这个示例看看生不生效~

// xxx.ets
import { Font } from '@kit.ArkUI';

@Entry
@Component
struct Index {
  @State message: string = 'Hello World';
  private uiContext: UIContext = this.getUIContext();
  private font: Font = this.uiContext.getFont();

  aboutToAppear() {
    this.font.registerFont({
      familyName: 'medium',
      familySrc: '/font/medium.ttf' // font文件夹与pages目录同级
    })
  }

  build() {
    Column() {
      Text(this.message)
        .align(Alignment.Center)
        .fontSize(20)
        .fontFamily('medium') // medium:注册自定义字体的名字($r('app.string.mediumFamilyName')、'mediumRawFile'等已注册字体也能正常使用)
    }.width('100%')
  }
}

字体文件应仅放置在src/main/resources/rawfile/fonts/目录下试试

onWindowStageCreate(windowStage: window.WindowStage): void {
  // Main window is created, set main page for this ability
  hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onWindowStageCreate');

  windowStage.loadContent('pages/Index', (err) => {
    font.registerFont({
      familyName:'canger_yuan_W01',
      familySrc:$rawfile('fonts/canger_yuan_W01.ttf')
    })

    if (err.code) {
      hilog.error(DOMAIN, 'testTag', 'Failed to load the content. Cause: %{public}s', JSON.stringify(err));
      return;
    }
    hilog.info(DOMAIN, 'testTag', 'Succeeded in loading the content.');
  });
}
  1. 字体管理中注册自定义字体

  2. 设置对应文本的字体家族。可参考以下代码:

// xxx.ets
import { Font } from '@kit.ArkUI';
@Entry
@Component
struct FontExample {
  @State message: string = 'Hello World';
  aboutToAppear() {
    // Register in black font
    let font: Font = this.getUIContext().getFont()
    font.registerFont({
      familyName: 'Condensed_Black', // Registered font name
      familySrc: '/font/Sans_Condensed_Black.ttf' // The font folder is at the same level as the pages directory
    })
    // Register in black oblique font
    font.registerFont({
      familyName: 'Condensed_Black_Italic', // Registered font name
      familySrc: '/font/Sans_Condensed_Black_Italic.ttf' // The font folder is at the same level as the pages directory
    })
  }
  build() {
    Column() {
      Text(this.message)
        .align(Alignment.Center)
        .fontSize(50)
        .fontFamily('Condensed_Black') // Use black font
      Text(this.message)
        .align(Alignment.Center)
        .fontSize(50)
        .fontFamily('Condensed_Black_Italic') // Use black oblique font
      Text(this.message)
        .align(Alignment.Center)
        .fontSize(50)
    }
    .width('100%')
    .margin({ top: 30 })
  }
}

效果如图所示: cke_970.png

请注意familyName参数 是否写的正确。

在HarmonyOS Next中,自定义字体无效通常是由于字体文件未正确放置在项目的resources/base/media/目录下,或未在ResourceManager中正确声明。请检查字体文件格式是否为.ttf.otf,并在resources/base/element/string.json中配置字体资源路径。确保在代码中使用ResourceManager加载字体时,路径与配置一致。

在HarmonyOS Next中,自定义字体无效通常由几个关键原因导致。从你的代码看,主要问题在于注册时机和资源引用方式

核心问题分析:

  1. 注册时机不当:在aboutToAppear中注册字体,此时UI可能已经开始渲染,导致字体应用不同步。font.getSystemFontList()返回的是系统预装字体,不包含动态注册的字体,因此检查方法无效。
  2. 资源引用错误$r('app.media.SIMYOU')用于引用resources/base/media/下的非字体资源(如图片),直接用于字体注册会导致加载失败。

正确做法:

1. 字体文件放置位置:.ttf.otf字体文件放置在: src/main/resources/rawfile/fonts/ 目录下(fonts子目录可自定义)。

2. 提前注册字体(推荐在Ability入口):EntryAbility.etsonWindowStageCreate中,loadContent之前完成字体注册。

// EntryAbility.ets
onWindowStageCreate(windowStage: window.WindowStage): void {
  // 先注册字体
  try {
    font.registerFont({
      familyName: 'mf1',
      familySrc: $rawfile('fonts/SIMYOU.ttf') // 使用$rawfile引用rawfile路径
    });
    console.log('自定义字体注册成功');
  } catch (err) {
    console.error('字体注册失败:', err);
  }

  // 再加载页面
  windowStage.loadContent('pages/test2', (err) => {
    if (err.code) {
      console.error('加载页面失败:', err);
    }
  });
}

3. 页面中直接使用: 注册成功后,在整个应用生命周期内均可直接使用该字体族名。

// test2.ets
Text('测试字体')
  .fontSize(30)
  .fontColor('#FFFFFF')
  .fontFamily('mf1') // 直接使用注册的familyName

关键点说明:

  • $rawfile('fonts/SIMYOU.ttf'):是引用rawfile目录下字体文件的正确方式,路径相对于resources/rawfile/
  • 无需重复注册:在Ability中注册一次即可全局使用,页面中无需再次注册。
  • 字体格式:确保字体文件完整且格式正确(如.ttf)。
  • 清除构建缓存:修改后,建议清理项目(Build > Clean Project)并重新运行。

按此调整后,自定义字体应能正常生效。

回到顶部