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

#### 问题现象

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

#### 背景知识

*   系统语言与区域：在设置的“语言和地区”中可以切换系统语言。
*   fontFamily：可以用于设置字体族。
*   registerFont：在字体管理中注册自定义字体。

#### 解决方案

定义状态变量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);
    };
  }
}
```