HarmonyOS鸿蒙Next中在应用中如何实现多语言动态切换?

HarmonyOS鸿蒙Next中在应用中如何实现多语言动态切换? 在应用中如何实现多语言动态切换?

4 回复

开发者你好,您也可以参考这个方案:

基于国际化-I18n实现应用内语言切换,使应用内语言设置不受系统语言设置的影响。

实现思路

  1. 在resources目录中,添加en_US/element/string.json文件和zh_CN/element/string.json文件,与base/element/string.json文件中的键同步设置对应所属语言的字符串值,其中base中设置默认显示的字符串值,zh_CN设置中文,en_US设置英文。
  2. 在ChoicePage.ets中,根据用户的选择设置应用偏好语言,可切换应用内语言的设置。
// 设置应用内偏好语言为简体中文
 Row() {
   Text('简体中文')
 }
 .onClick(() => {
   this.isEnglish = false;
   i18n.System.setAppPreferredLanguage('zh-Hans');
 })

 // 设置应用内偏好语言为英文
 Row() {
   Text('English')
 }
 .onClick(() => {
   this.isEnglish = true;
   i18n.System.setAppPreferredLanguage('en-Latn-US');
 })

 // 获取应用当前设置的偏好语言
 let appPreferredLanguage: string = i18n.System.getAppPreferredLanguage();
 if (appPreferredLanguage === 'en-Latn-US') {
   this.isEnglish = true;
 } else if (appPreferredLanguage === 'zh-Hans') {
   this.isEnglish = false;
 }

参考链接:应用内语言切换

更多关于HarmonyOS鸿蒙Next中在应用中如何实现多语言动态切换?的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


场景介绍

在面向全球用户的应用开发时,我们就需要支持多语言来进行应用语言的转换。

实现思路

资源目录结构规范

resources 目录下按语言创建子目录,如:然后可以通过使用 $r('app.string.xxx') 引用字符串资源

resources/
  ├── base/               # 默认
  ├── zh-CN/              # 中文
  ├── en-US/              # 英语
  └── rawfile/            # 其他

动态切换语言的核心

首先通过 AppStorage 来存储用户选择的语言信息

然后调用 resourceManager.updateConfiguration() 更新资源配置

最后使用 @Observed + @ObjectLink 响应式更新触发 UI 刷新

完整代码示例

resources/zh-CN/string.json

{
  "hello": "你好,世界!",
  "switch_lang": "切换为英文"
}

resources/en-US/string.json

{
  "hello": "Hello, World!",
  "switch_lang": "Switch to Chinese"
}
import resourceManager from '@ohos.resourceManager';
import { BusinessError } from '@ohos.base';

@Entry
@Component
struct MainUI {
  @State currentLang: string = 'en-US';
  @State message: string = $r('app.string.hello');
  @State switchBtnText: string = $r('app.string.switch_lang');

  aboutToAppear() {
    // 初始化语言
    this.loadLanguage();
  }

  async loadLanguage() {
    try {
      const resMgr = await resourceManager.getResourceManager();
      const config = await resMgr.getConfiguration();
      this.currentLang = config.locale;
      this.refreshStrings();
    } catch (error) {
      console.error(`Failed to get config: ${error}`);
    }
  }

  async switchLanguage() {
    const newLang = this.currentlang === 'zh-CN' ? 'en-US' : 'zh-CN';
    try {
      const resMgr = await resourceManager.getResourceManager();
      const config = await resMgr.getConfiguration();
      config.setLocale(newLang);
      await resMgr.updateConfiguration(config);

      // 保存选择(可选)
      // preferences.set('app_language', newLang);

      this.currentLang = newLang;
      this.refreshStrings();
    } catch (error) {
      console.error(`Switch language failed: ${error}`);
    }
  }

  refreshStrings() {
    // 手动重新获取字符串
    this.message = $r('app.string.hello').toString();
    this.switchBtnText = $r('app.string.switch_lang').toString();
  }

  build() {
    Column() {
      Text(this.message)
        .fontSize(24)
        .margin(20)

      Button(this.switchBtnText)
        .onClick(() => {
          this.switchLanguage();
        })
        .margin(20)
    }
    .width('100%')
    .height('100%')
  }
}

在HarmonyOS Next中实现多语言动态切换,需使用ResourceManager模块。首先在resources目录下按语言配置字符串资源,如zh_CNen_US。应用内通过resourceManager.getResourceManager()获取资源管理器,调用updateConfiguration方法更新语言配置,并配合context.restartBundle()重启界面以生效。

在HarmonyOS Next中,实现应用内多语言动态切换的核心是使用ResourceManagerintl模块,并监听系统语言配置的变化。以下是关键步骤和代码示例:

1. 准备多语言资源文件

resources目录下按语言代码(如zh-CNen-US)创建子目录,并在其中放置string.json等资源文件。

示例:resources/zh-CN/string.json

{
  "string": [
    {
      "name": "hello",
      "value": "你好"
    }
  ]
}

2. 获取与监听ResourceManager

在UIAbility或页面中获取ResourceManager,并订阅系统语言变化事件。

在UIAbility中订阅语言变化:

import { UIAbility } from '@kit.AbilityKit';
import { BusinessError } from '@kit.BasicServicesKit';
import { common } from '@kit.AbilityKit';

export default class EntryAbility extends UIAbility {
  onWindowStageCreate(windowStage: window.WindowStage): void {
    // 获取ResourceManager
    let resMgr = this.context.resourceManager;
    // 订阅系统语言配置变化
    try {
      resMgr.on('configChange', (event: common.Configuration): void => {
        // 当语言发生变化时,重新加载页面或更新UI
        // 例如:重新启动当前页面或发送事件通知
        console.info('Language changed');
      });
    } catch (error) {
      const err: BusinessError = error as BusinessError;
      console.error(`Failed to subscribe configChange. Code: ${err.code}, message: ${err.message}`);
    }
    // ... 其他初始化代码
  }
}

3. 动态获取字符串资源

在页面中,通过ResourceManager根据当前配置获取对应语言的字符串。

在页面中使用:

import { common } from '@kit.AbilityKit';
import { BusinessError } from '@kit.BasicServicesKit';

@Entry
@Component
struct Index {
  private resMgr: common.ResourceManager = getContext().resourceManager;
  @State message: string = '';

  aboutToAppear(): void {
    this.updateMessage();
  }

  // 更新文本内容
  private updateMessage(): void {
    this.resMgr.getStringValue($r('app.string.hello').id)
      .then((value: string) => {
        this.message = value;
      })
      .catch((error: BusinessError) => {
        console.error(`Failed to get string value. Code: ${error.code}, message: ${error.message}`);
      });
  }

  build() {
    Row() {
      Column() {
        Text(this.message)
          .fontSize(50)
          .fontWeight(FontWeight.Bold)
        // 可以添加一个按钮来触发语言切换测试
        Button('Switch Language')
          .onClick(() => {
            // 注意:应用内动态切换语言通常需要改变系统设置或模拟配置更新。
            // 实际开发中,你可能需要调用配置更新API(如果提供)或重启UIAbility来应用新语言。
            // 此处仅为示例结构。
            console.info('Attempt to switch language');
          })
      }
      .width('100%')
    }
    .height('100%')
  }
}

4. 处理语言切换逻辑

要实现真正的动态切换,通常需要:

  • 更新系统配置(需权限):通过settings模块修改系统语言设置(这会影响整个设备)。
  • 应用内覆盖:如果只想在应用内切换,可以维护一个自定义的语言偏好设置,并在每次获取资源时优先使用该设置(而非系统设置)。这需要自行封装资源获取逻辑。

应用内覆盖示例思路:

// 1. 持久化存储用户选择的语言代码(例如使用Preferences)
// 2. 封装一个函数,优先从Preferences中读取语言代码
// 3. 使用ResourceManager.getResourceManager(locale: string)获取指定语言的ResourceManager实例
// 4. 用该实例获取字符串资源

注意事项

  • 动态切换语言可能涉及UIAbility的重启(如配置变化触发onConfigurationUpdate)以实现界面全面更新。
  • 确保所有UI文本都通过资源ID获取,避免硬编码。
  • 测试时注意设备或模拟器的系统语言设置。

通过以上步骤,你可以在HarmonyOS Next应用中实现多语言动态切换。

回到顶部