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

#### 问题现象

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

#### 背景知识

*   [系统语言与区域](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/i18n-system-language-region)：在设置的“语言和地区”中可以切换系统语言。
*   [fontFamily](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/ts-basic-components-text#fontfamily)：可以用于设置字体族。
*   [registerFont](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/arkts-apis-uicontext-font#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);
    };
  }
}