HarmonyOS鸿蒙Next ArkTS中如何实现国际化(i18n)的复数规则?

HarmonyOS鸿蒙Next ArkTS中如何实现国际化(i18n)的复数规则? 英文需根据数量显示不同文本,但 $r('app.string.items') 仅支持静态字符串,如何实现国际化(i18n)的复数规则?(如 “1 item” vs “2 items”)

8 回复

开发者您好,可以参考下:getIntPluralStringValueSync: 获取指定资源ID对应的单复数字符串,并根据args参数对字符串进行格式化,使用同步方式返回。

说明

  • 中文环境下,字符串不区分单复数;其他语言环境下,字符串区分单复数,具体规则参考语言单复数规则
  • 在英语、德语等语言中,单复数类型包括基数词(如1、2、3)和序数词(如1st、2nd、3rd),本接口仅支持在基数词类型下使用。

示例代码如下:

// 资源文件路径: src/main/resources/base/element/plural.json
{
  "plural": [
    {
      "name": "format_test",
      "value": [
        {
          "quantity": "one",
          "value": "There is %d apple in the %s, the total amount is %f kg."
        },
        {
          "quantity": "other",
          "value": "There are %d apples in the %s, the total amount is %f kg."
        }
      ]
    }
  ]
}
import { AbilityConstant, UIAbility, Want } from '@kit.AbilityKit';
import { BusinessError } from '@kit.BasicServicesKit';

export default class EntryAbility extends UIAbility {
    onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void {
        try {
            // 根据语言单复数规则,参数num取值为1,英文环境下对应单复数类别为one
            // 在资源文件中用quantity字段表示单复数类别,因此会获取quantity为one的字符串
            // 'app.plural.format_test'仅作示例,请替换为实际使用的资源
            let pluralStr = this.context.resourceManager.getIntPluralStringValueSync($r('app.plural.format_test').id, 1, 1, "basket", 0.3);
            console.info(`getIntPluralStringValueSync, result: ${pluralStr}`);
            // 打印输出结果: getIntPluralStringValueSync, result: There is 1 apple in the basket, the total amount is 0.3 kg.
        } catch (error) {
            let code = (error as BusinessError).code;
            let message = (error as BusinessError).message;
            console.error(`getIntPluralStringValueSync failed, error code: ${code}, message: ${message}.`);
        }
    }
}

更多关于HarmonyOS鸿蒙Next ArkTS中如何实现国际化(i18n)的复数规则?的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


这样不行吗?

num > 1 ?$r('app.string.items'):$r('app.string.item')

帮你搜索了一下,还没有实测,参考一下:

一、核心实现步骤

步骤 1:配置多语言复数资源文件

按鸿蒙国际化规范,在 resources 目录下为目标语言(如英文、中文)配置复数规则,核心是按 one/other(英文)、other(中文)定义结构化值:

1.1 英文资源(en_US/element/string.json)

{
  "string": [
    {
      "name": "items",
      "value": {
        "one": "{count} item",   // 数量=1 时生效
        "other": "{count} items" // 数量≠1(0/2/3...)时生效
      }
    },
    {
      "name": "apples",
      "value": {
        "one": "{count} apple",
        "other": "{count} apples"
      }
    }
  ]
}

1.2 中文资源(zh_CN/element/string.json)

中文无复数规则,仅需配置 other(所有数量通用):

{
  "string": [
    {
      "name": "items",
      "value": {
        "other": "{count} 个项目"
      }
    },
    {
      "name": "apples",
      "value": {
        "other": "{count} 个苹果"
      }
    }
  ]
}

步骤 2:组件内使用 $tc () 动态渲染复数文本

$tc() 是 HarmonyOS 5.0+ 内置方法(无需额外依赖),直接传入「资源键、数量、占位符参数」即可自动匹配复数规则:

// 无需导入额外依赖(5.0+ 内置 $tc 全局可用)
@Entry
@Component
struct PluralDemo {
  // 动态数量(绑定UI交互,实时更新)
  @State itemCount: number = 1;
  @State appleCount: number = 0;

  build() {
    Column() {
      // 1. 项目数量:1→"1 item" / 2→"2 items"(英文);1→"1个项目" / 2→"2个项目"(中文)
      Text($tc('app.string.items', this.itemCount, { count: this.itemCount }))
        .fontSize(20)
        .margin(10);

      // 2. 苹果数量:0→"0 apples"(英文)/ "0个苹果"(中文)
      Text($tc('app.string.apples', this.appleCount, { count: this.appleCount }))
        .fontSize(20)
        .margin(10);

      // 3. 交互按钮:修改数量,复数文本自动刷新
      Button("项目数量+1")
        .onClick(() => this.itemCount++)
        .backgroundColor("#007AFF")
        .margin(10);
    }
    .width('100%')
    .height('100%')
    .justifyContent(FlexAlign.Center);
  }
}

二、关键注意事项

  1. 资源键格式:必须写 app.string.xxx(如 app.string.items),不要加 resources 前缀,否则会找不到资源;
  2. 占位符匹配:资源文件中的 {count} 需与 $tc() 第三个参数的键名完全一致(如 { count: this.itemCount });
  3. 复数类别兜底:所有语言的资源文件都要保留 other 类别(鸿蒙 5.0+ 会自动兜底,避免文本缺失);
  4. 语言切换生效:修改设备语言后,无需重启 App,$tc() 会自动读取对应语言的资源文件。

三、核心要点总结

  1. HarmonyOS 5.0+ 下,$tc('app.string.资源名', 数量, { count: 数量 }) 是实现复数国际化的最优解,替代静态 $r()
  2. 英文配置 one/other 复数类别,中文仅需配置 other
  3. 核心避坑点:资源键格式为 app.string.xxx、占位符键名与资源文件一致。

目前没办法直接通过 JSON 字符串资源去实现复数规则的国际化。 最简单的方法就是使用三元运算符去判断是否显示复数的资源。

// resources/base/string.json
{
  "string": [
    {
      "name": "item",
      "value": "item"
    },
    {
      "name": "items",
      "value": "items"
    }
  ]
}
// index.ets
@Entry
@ComponentV2
struct Index {
  @Local count: number = 10;

  @Computed
  get string() {
    return `${this.count} ${this.count > 1 ? $r('app.string.items') : $r('app.string.item')}`;
  }

  build() {
    Column() {
      Text(this.string)
    }
    .height('100%')
    .width('100%')
  }
}

HarmonyOS 资源系统不内置复数规则,需自行处理:

  • resources/base/string.json 中定义多个 key:
"item_count_one": "1 item",
"item_count_other": "{} items"
  • 代码中判断:
getText(count: number): string {
  if (count === 1) return $r('app.string.item_count_one');
  return $r('app.string.item_count_other').replace('{}', count.toString());
}
  • 更复杂语言(如阿拉伯语)需按规则扩展。

一般APP内的非固定文字,例如价格啥的,都是服务器返回字符串。返回啥就显示啥。完全不需要自己搞什么复数哦。

在ArkTS中实现国际化复数规则,使用I18n模块的getPluralString方法。首先导入i18n模块,然后调用getPluralString函数,传入资源键名、数量值及可选参数。系统会根据数量自动匹配复数形式(如单数、复数等),资源需在i18n目录下的JSON文件中定义对应规则。例如:i18n.getPluralString($r('app.string.quantity'), count)。确保资源文件正确配置复数条目。

在HarmonyOS Next的ArkTS中,可以通过资源限定符和$r的动态参数功能来实现国际化的复数规则。

具体步骤如下:

  1. 定义带数量参数的字符串资源: 在resources/base/element/string.json中,定义包含占位符的字符串。例如:

    {
      "string": [
        {
          "name": "item_count",
          "value": "%d item"
        }
      ]
    }
    
  2. 为特定语言定义复数形式: 在对应语言的资源目录下(如resources/en-US/element/string.json),使用ArkTS的复数语法规则定义不同数量的字符串。语法为{pluralType, select, ...}。 例如,为美式英语定义单复数:

    {
      "string": [
        {
          "name": "item_count",
          "value": "{count, plural, =0 {No items} =1 {1 item} other {%d items}}"
        }
      ]
    }
    

    这里:

    • count 是传入的参数名。
    • plural 表示启用复数处理。
    • =0=1 是具体的数量匹配规则。
    • other 是默认规则。
    • %d 会动态替换为传入的数值。
  3. 在ArkTS代码中调用并传入参数: 使用$r引用资源,并通过第二个参数传入一个对象,对象的键名需与资源中定义的参数名(如count)一致。

    let count: number = 5;
    // 直接传入参数对象,系统会根据当前语言环境和数量自动选择正确的字符串格式。
    Text($r('app.string.item_count', { count: count }))
    

    count为1时,显示“1 item”;为5时,显示“5 items”;为0时,显示“No items”。

关键点

  • 基础资源文件(base)中建议提供一个通用的、包含占位符的字符串作为回退。
  • 在具体的语言资源文件中,使用{参数名, plural, select, ...}语法来定义该语言下的复数规则。不同语言的复数规则(如单数、复数、两种复数形式等)可以在此灵活定义。
  • 调用时$r('app.string.xxx', {参数名: 数值}),传入的参数对象会用于驱动复数选择逻辑。

这样即可实现根据动态数量显示不同国际化文本的需求。

回到顶部