HarmonyOS鸿蒙Next中ResourceManager如何实现多语言、多地区资源的动态切换?

HarmonyOS鸿蒙Next中ResourceManager如何实现多语言、多地区资源的动态切换? App 支持中/英/阿语,用户希望在 App 内切换语言而不重启。鸿蒙能否像 Android 那样动态更换 Configuration?还是必须重启 Ability?

6 回复

【解决方案】

开发者您好,采用以下方案可解决您应用多语言功能切换问题,看是否满足您的需求,还是一定需要ResourceManager来实现,具体步骤如下:

  1. 在entry模块resource目录下分别创建中、英文资源文件。 zh_CN/element/string.json文件如下:

    {
      "string": [
        {
          "name": "module_desc",
          "value": "module description"
        },
        {
          "name": "EntryAbility_desc",
          "value": "description"
        },
        {
          "name": "EntryAbility_label",
          "value": "label"
        },
        {
          "name": "title",
          "value": "中文标题"
        }
      ]
    }
    

    en_US/element/string.json如下:

    {
      "string": [
        {
          "name": "module_desc",
          "value": "module description"
        },
        {
          "name": "EntryAbility_desc",
          "value": "description"
        },
        {
          "name": "EntryAbility_label",
          "value": "label"
        },
        {
          "name": "title",
          "value": "English title"
        }
      ]
    }
    
  2. 使用setAppPreferredLanguage设置应用语言切换能力,应用内语言不再随系统语言改变而改变。 关键代码如下:

    Button('应用内切换中文')
      .margin({ bottom: 10 })
      .onClick(() => {
        try {
          i18n.System.setAppPreferredLanguage('zh-CN');
        } catch (e) {
          hilog.error(0x0000, TAG, `error = ${JSON.stringify(e)}`);
        }
      })
    
    Button('应用内切换英文')
      .margin({ bottom: 10 })
      .onClick(() => {
        try {
          i18n.System.setAppPreferredLanguage('en-US');
        } catch (e) {
          hilog.error(0x0000, TAG, `error = ${JSON.stringify(e)}`);
        }
      })
    

完整代码如下:

import hilog from '@ohos.hilog';
import { common } from '@kit.AbilityKit';
import { promptAction } from '@kit.ArkUI';
import i18n from '@ohos.i18n';
import { http } from '@kit.NetworkKit';
import fs from '@ohos.file.fs';
import { BusinessError } from '@ohos.base';

const TAG = 'testTag';

@Entry
@Component
struct Index {
  context = this.getUIContext().getHostContext() as common.UIAbilityContext;
  filePath: string = '';

  build() {
    Column() {
      Text($r('app.string.title'))
        .fontSize($r('app.float.page_text_font_size'))
        .fontWeight(FontWeight.Bold)
        .alignRules({
          center: { anchor: '__container__', align: VerticalAlign.Center },
          middle: { anchor: '__container__', align: HorizontalAlign.Center }
        })
        .margin({ top: 30, bottom: 30 })

      Button('应用内切换中文')
        .margin({ bottom: 10 })
        .onClick(() => {
          try {
            i18n.System.setAppPreferredLanguage('zh-CN');
          } catch (e) {
            hilog.error(0x0000, TAG, `error = ${JSON.stringify(e)}`);
          }
        })

      Button('应用内切换英文')
        .margin({ bottom: 10 })
        .onClick(() => {
          try {
            i18n.System.setAppPreferredLanguage('en-US');
          } catch (e) {
            hilog.error(0x0000, TAG, `error = ${JSON.stringify(e)}`);
          }
        })
    }
    .height('100%')
    .width('100%')
  }
}

也可以参考官网行业实践示例:应用内语言切换

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


I18n.System.setAppPreferredLanguage(id)

通过配置呗

HarmonyOS Next中ResourceManager通过资源索引表(resources.index)和资源目录结构实现多语言/地区动态切换。应用启动时自动加载设备当前语言区域对应的资源文件,运行时可通过ResourceManager.getSystem().getConfiguration()获取当前配置,使用updateConfiguration()方法动态更新语言区域设置。资源文件按element/string.json格式存储在resources/目录下,按zh_CN等语言代码分目录存放。

在HarmonyOS Next中,ResourceManager支持应用内动态切换语言和地区,无需重启Ability。

核心是通过ResourceManager.updateConfiguration方法更新配置,并配合UIAbility.onConfigurationUpdate回调或@ohos.i18n模块的监听机制来实现界面刷新。

关键实现步骤:

  1. 更新全局配置:调用ResourceManager.updateConfiguration,传入新的Configuration对象(设置languageregion参数)。

    import { i18n, Configuration } from '@kit.I18nKit';
    
    // 获取当前配置
    let config: Configuration = i18n.getSystemConfiguration();
    // 修改为目标语言和地区,例如切换至阿拉伯语/沙特地区
    config.language = 'ar';
    config.region = 'SA';
    // 更新应用配置
    let resMgr = getContext().resourceManager;
    await resMgr.updateConfiguration(config);
    
  2. 刷新界面:有两种主流方式处理界面更新:

    • 方式一:在UIAbility中监听配置变更。重写onConfigurationUpdate生命周期回调,在此方法中重新加载页面或触发UI组件刷新。
      // UIAbility的onConfigurationUpdate回调中
      onConfigurationUpdate(newConfig: Configuration): void {
          // 通知所有页面或使用状态管理工具触发UI刷新
          // 例如,通过AppStorage发布配置更新事件
          AppStorage.setOrCreate('appLocale', newConfig);
      }
      
    • 方式二:在页面或组件中监听配置变更。使用@ohos.i18non('systemLanguageChange')等事件,或在自定义状态管理(如AppStorage)中绑定响应式变量,当配置变更时自动触发UI重建。
  3. 资源获取:更新配置后,通过ResourceManager获取字符串等资源时会自动匹配当前生效的语言和地区设置。

    let value = await resMgr.getString($r('app.string.hello').id);
    

与Android的对比: 机制与Android的Resources.updateConfiguration(已废弃)或Context.createConfigurationContext思路类似,通过更新Configuration并通知UI刷新来实现。HarmonyOS Next提供了更集成的生命周期回调(onConfigurationUpdate)来简化处理。

注意事项

  • 动态切换主要影响的是应用内通过ResourceManager读取的资源。系统界面(如通知栏)的语言通常跟随系统设置。
  • 部分系统能力(如某些系统弹窗的文本)可能仍依赖应用重启才能完全生效。
  • 建议将语言配置持久化(如使用Preferences存储),应用下次启动时自动设置为用户上次选择的语言。

此方案允许用户在不重启应用的前提下,实现中、英、阿语等语言资源的即时切换。

回到顶部