目录

如何根据系统语言动态切换字体

问题现象

在设置-系统-语言和地区中切换字体以后,能否让应用内字体也跟随切换?比如当系统语言设置成中文时,使用默认字体'HarmonyOS Sans',当系统语言设置成英文时,使用自定义字体。

背景知识

解决方案

定义状态变量fontFamily并绑定在Text组件上,注册系统语言变化监听,当系统语言变化时修改fontFamily的值,即可实现根据系统语言动态切换字体,实现步骤如下:

  1. 注册自定义字体。
    let font: Font = this.getUIContext().getFont();
    font.registerFont({
      familyName: 'customFont', // 注册的字体名称
      familySrc: $rawfile('customFont.ttf') // rawfile目录下的自定义字体文件
    });
  2. 注册系统语言变化监听,在收到监听后根据语言类型进行字体族切换。
    // 通过监听公共事件COMMON_EVENT_LOCALE_CHANGED可以感知系统语言、系统地区或系统区域变化
    let subscriber: commonEventManager.CommonEventSubscriber;
    let subscribeInfo: commonEventManager.CommonEventSubscribeInfo = {
      events: [commonEventManager.Support.COMMON_EVENT_LOCALE_CHANGED]
    };
    commonEventManager.createSubscriber(subscribeInfo)
      .then((commonEventSubscriber: commonEventManager.CommonEventSubscriber) => {
        console.info('CreateSubscriber');
        subscriber = commonEventSubscriber;
        commonEventManager.subscribe(subscriber, (err) => {
          if (err) {
            console.error(`Failed to subscribe common event. error code: ${err.code}, message: ${err.message}.`);
            return;
          }
          let systemLanguage: string = i18n.System.getSystemLanguage(); // systemLanguage为当前系统语言
          if (systemLanguage === 'zh-Hans') {
            this.fontFamily = 'HarmonyOS Sans';
          } else {
            this.fontFamily = 'customFont';
          }
        });
      })
      .catch((err: BusinessError) => {
        console.error(`CreateSubscriber failed, code is ${err.code}, message is ${err.message}`);
      });

完整示例代码如下:

import { Font } from '@kit.ArkUI';
import { i18n } from '@kit.LocalizationKit';
import { BusinessError, commonEventManager } from '@kit.BasicServicesKit';

@Entry
@Component
struct ChangeFontFamilyBySystemLanguage {
  @State fontFamily: string = 'HarmonyOS Sans';

  aboutToAppear(): void {
    let font: Font = this.getUIContext().getFont();
    font.registerFont({
      familyName: 'customFont', // 注册的字体名称
      familySrc: $rawfile('customFont.ttf') // rawfile目录下的自定义字体文件
    });
    // 通过监听公共事件COMMON_EVENT_LOCALE_CHANGED可以感知系统语言、系统地区或系统区域变化
    let subscriber: commonEventManager.CommonEventSubscriber;
    let subscribeInfo: commonEventManager.CommonEventSubscribeInfo = {
      events: [commonEventManager.Support.COMMON_EVENT_LOCALE_CHANGED]
    };
    commonEventManager.createSubscriber(subscribeInfo)
      .then((commonEventSubscriber: commonEventManager.CommonEventSubscriber) => {
        console.info('CreateSubscriber');
        subscriber = commonEventSubscriber;
        commonEventManager.subscribe(subscriber, (err) => {
          if (err) {
            console.error(`Failed to subscribe common event. error code: ${err.code}, message: ${err.message}.`);
            return;
          }
          let systemLanguage: string = i18n.System.getSystemLanguage(); // systemLanguage为当前系统语言
          if (systemLanguage === 'zh-Hans') {
            this.fontFamily = 'HarmonyOS Sans';
          } else {
            this.fontFamily = 'customFont';
          }
        });
      })
      .catch((err: BusinessError) => {
        console.error(`CreateSubscriber failed, code is ${err.code}, message is ${err.message}`);
      });
  }

  build() {
    Column() {
      Row() {
        Text('Hello World')
          .fontSize(50)
          .fontFamily(this.fontFamily);
      }.width('100%').justifyContent(FlexAlign.Center);
    };
  }
}