#2023盲盒+码# OpenHarmony国际化I18n开发 原创 精华

zhushangyuan_
发布于 2023-9-3 08:13
浏览
0收藏

【本文正在参加 2023「盲盒」+码有奖征文活动】 https://ost.51cto.com/posts/25284

 :book: 查看本文案例

OpenHarmony国际化I18n开发范例

概念介绍

在开发应用中可能会遇到多国家多地区场景,应用要提供不同的语言、时间、时区给目标用户和市场,开发者往往需要提供多个不同版本以保证不同地区用户方便使用

本例基于国际化示例应用,为大家介绍I18n组件,该组件提供系统相关的或者增强的国际化能力。

#2023盲盒+码# OpenHarmony国际化I18n开发-鸿蒙开发者社区

接口

I18n官方文档 @ohos.i18n

类名 接口名称 描述
System getDisplayCountry(country:string,locale:string,sentenceCase?:boolean):string<sup>9+</sup> 获取国家的本地化表示。
System getDisplayLanguage(language:string,locale:string,sentenceCase?:boolean):string<sup>9+</sup> 获取语言的本地化表示。
System getSystemLanguages():Array<string><sup>9+</sup> 获取系统语言列表。
System getSystemCountries(language: string):Array<string><sup>9+</sup> 获取针对输入语言系统支持的国家或地区列表。
System isSuggested(language: string, region?: string): boolean<sup>9+</sup> 判断当前语言和地区是否匹配
System getSystemLanguage():string<sup>9+</sup> 获取系统语言。
System setSystemLanguage(language: string)<sup>9+</sup> 设置系统语言。
System getSystemRegion():string<sup>9+</sup> 获取系统地区。
System setSystemRegion(region: string)<sup>9+</sup> 设置系统地区。
System getSystemLocale():string<sup>9+</sup> 获取系统Locale。
System setSystemLocale(locale: string)<sup>9+</sup> 设置系统Locale。
System is24HourClock():boolean<sup>9+</sup> 判断系统时间是否为24小时制。
System set24HourClock():boolean<sup>9+</sup> 修改系统时间的24小时制设置。
System addPreferredLanguage(language: string, index?: number)<sup>9+</sup> 在系统偏好语言列表的指定位置添加偏好语言。
System removePreferredLanguage(index: number)<sup>9+</sup> 删除系统偏好语言列表中指定位置的偏好语言。
System getPreferredLanguageList()<sup>9+</sup> 获取系统偏好语言列表。
System getFirstPreferredLanguage()<sup>9+</sup> 获取系统偏好语言列表中的第一个偏好语言。
System getAppPreferredLanguage()<sup>9+</sup> 获取应用偏好语言。
System setUsingLocalDigit(flag: boolean)<sup>9+</sup> 设置系统是否使用本地数字。
System getUsingLocalDigit()<sup>9+</sup> 判断系统是否使用本地数字。
isRTL(locale:string):boolean<sup>9+</sup> locale对应的语言是否为从右到左语言。

具体实现

配置文件

应用需要在项目的module.json5配置文件中逐个声明所需的权限,否则应用将无法获取授权

在配置文件的requestPermissions属性数组中配置所需的权限,包含3个属性

{
  ...
  "requestPermissions": [
    {
      "name": "ohos.permission.UPDATE_CONFIGURATION"
    },
    {
      "name": "ohos.permission.SET_TIME_ZONE"
    },
    {
      "name": "ohos.permission.SET_TIME"
    }
  ]
}

1.更新配置权限:ohos.permission.UPDATE_CONFIGURATION

2.设置时区权限:ohos.permission.SET_TIME_ZONE

3.设置系统时间权限:ohos.permission.SET_TIME

引入I18n模块

import i18n from '@ohos.i18n';

语言和地区

  • 使用getSystemRegion和getSystemLocale分别获取当前系统地区和系统区域,并传入getDisplayCountry获取指定国家的本地化显示文本
this.currentRegion = i18n.System.getDisplayCountry(i18n.System.getSystemRegion(), i18n.System.getSystemLocale());
  • 使用getSystemLanguage获取当前系统支持的语言列表
  this.localLanguage = i18n.System.getSystemLanguage();
  • 使用getSystemCountries方法获取针对输入语言系统支持的国家或地区列表,随后可以遍历列表,并且调用isSuggested方法判断当前语言和地区是否匹配
 try {
  this.countryIds = i18n.System.getSystemCountries(this.currentRegion);
  } catch (err) {
  Logger.error(`getSystemCountries failed, code is ${err.code}, message is ${err.message}`);
  }
this.countryIds.forEach(id => {
  let country = i18n.System.getDisplayCountry(id, this.localLanguage);
  this.countries.push({ key: country, value: '' });
  let isSuggested: boolean;
  try {
    isSuggested = i18n.System.isSuggested(this.localLanguage, id);
  } catch (err) {
    Logger.error(`isSuggested failed, code is ${err.code}, message is ${err.message}`);
  }
  if (isSuggested) {
    this.suggestIds.push(id);
    this.suggestCounties.push({ key: country, value: '' });
  }
})
  • 实现某时区城市在该区域的本地化显示列表:
    使用getAvailableZoneCityIDs获取系统支持的时区城市ID
    使用getCityDisplayName格式化
 getTimeZoneSrc() {
  this.timeZoneSrc = [];
  let zoneCityIDs = i18n.TimeZone.getAvailableZoneCityIDs();
  for (let zoneCityId of zoneCityIDs) {
    let cityDisplayName = i18n.TimeZone.getCityDisplayName(zoneCityId, "zh-Hans");
    let timeZone = i18n.TimeZone.getTimezoneFromCity(zoneCityId);
    this.timeZoneSrc.push({
      key: timeZone.getID(),
      timeZone: timeZone,
      display: cityDisplayName
    });
  };
}

#2023盲盒+码# OpenHarmony国际化I18n开发-鸿蒙开发者社区

日期和时间

  • 引入systemDateTime模块获取当前系统时间和时区
  • 引入Intl模块,该模块提供基础的应用国际化能力,包括时间日期格式化、数字格式化、排序等
import systemDateTime from '@ohos.systemDateTime';
import Intl from '@ohos.intl';

systemDateTime模块官方文档@ohos.systemDateTime
intl模块官方文档@ohos.intl

  • 编写格式化时间方法
    Intl.DateTimeFormat方法用来创建时间日期格式化对象
    使用时间日期格式化对象的format方法格式化时间日期字符串
 getDateString() {
    let locale = i18n.System.getSystemLocale();
    let language = i18n.System.getSystemLanguage();
    let params = [language, locale];
    let dateFormat = new Intl.DateTimeFormat(params, options);
    let date = new Date();
    let formatString = dateFormat.format(date);
    if (language === 'zh-Hans') {
      let format = formatString.split(' ');
      return [format[0], format[1]];
    } else {
      let format = formatString.split(', ');
      return [`${format[0]}, ${format[1]}`, format[2]];
    }
  }
  • 格式化时区:
    getRawOffset方法用来获取时区对象表示的时区与UTC时区的偏差
    getSystemLanguage方法获取系统语言
    getDisplayName方法用来获取时区对象的本地化表示
getTimeZoneString(timeZone: i18n.TimeZone) {
  let offset = timeZone.getRawOffset();
  return `GMT${offset > 0 ? '+' : '-'}${this.getTimeString(offset)}  ${timeZone.getDisplayName(i18n.System.getSystemLanguage())}`;
}

上述代码中通过判断偏差来格式化时区显示

  • 获取系统时间后调用I18n的getTimeZone方法获取系统时区并使用上述方法格式化
 getTimeDisplay() {
    let timeZone = await systemTime.getTimezone();
    let zone = i18n.getTimeZone(timeZone);
    this.timeZone = this.getTimeZoneString(zone);
    let timeInfo = this.getDateString();
    this.date = timeInfo[0];
    this.time = timeInfo[1];
  }

#2023盲盒+码# OpenHarmony国际化I18n开发-鸿蒙开发者社区

区域格式示例

本模块进入界面展示当前区域,当前系统语言下的时间、数字、货币、百分比、单复数、屏幕方向等信息的格式化显示。

  build() {
    Column() {
      TitleBar({ hasBackPress: true, title: $r('app.string.format_example') })
      this.TextView({ text: this.language })
      Column() {
        this.TextView({ text: this.date })
        this.TextView({ text: this.time })
        ForEach(this.numberFormat, (item, index) => {
          this.TextView({ text: item });
        }, item => item)
        this.TextView({ text: this.pluralFormat })
        this.TextView({ text: this.timeZoneDetect })
        this.TextView({ text: this.normalizer })
        this.TextView({ text: this.mDirection })
      }

页面代码中的language、data和time已经在上述方法中获取到,下面分别看一下剩下的数据如何获取

  • numberFormat
  getNumberFormatString() {
    let currentLocale = new Intl.Locale();
    let locale = i18n.System.getSystemLocale();
    let numfmt = new Intl.NumberFormat();
    let options = numfmt.resolvedOptions();
    options.locale = locale;
    options.numberingSystem = currentLocale.numberingSystem;
    options.currency = 'CNY';
    options.currencySign = 'symbol';
    options.localeMatcher = 'best fit';
    options.style = 'decimal';
    let params = [i18n.System.getSystemLanguage(), locale];
    let numberFormat = new Intl.NumberFormat(params, options);
    options.style = 'currency';
    let currencyFormat = new Intl.NumberFormat(params, options);
    options.style = 'percent';
    let percentFormat = new Intl.NumberFormat(params, options);
    // 此处返回的只是一个示例,因此1234567,123456,78.9并不具有实际意义
    return [numberFormat.format(1234567), currencyFormat.format(123456), percentFormat.format(78.9)];
  }

该方法主要使用Intl.NumberFormat()方法创建数字格式化对象
示例:

// 使用 en-GB locale创建NumberFormat对象,style设置为decimal,notation设置为scientific
let numfmt = new Intl.NumberFormat("en-GB", {style:'decimal', notation:"scientific"});

NumberFormat对象中resolvedOptions方法用来获取该对象的格式化选项

  • NumberFormat对象的部分选项
名称 类型 可读 可写 说明
locale string 区域参数, 如:“zh-Hans-CN”。locale属性默认值为系统Locale。
currency string 货币单位, 如:“EUR”,“CNY”,"USD"等。
currencySign string 货币单位的符号显示,取值包括: “symbol”,“narrowSymbol”,“code”,“name” 。currencySign属性默认值为standard。
localeMatcher string 要使用的区域匹配算法,取值包括:“lookup”, “best fit”。localeMatcher属性默认值为best fit。
style string 数字的显示格式,取值包括:“decimal”, “currency”, “percent”, “unit”。style属性默认值为decimal。
numberingSystem string 数字系统,取值包括:“adlm”, “ahom”, “arab”, “arabext”, “bali”, “beng”, “bhks”, “brah”, “cakm”, “cham”, “deva”, “diak”, “fullwide”, “gong”, “gonm”, “gujr”, “guru”, “hanidec”, “hmng”, “hmnp”, “java”, “kali”, “khmr”, “knda”, “lana”, “lanatham”, “laoo”, “latn”, “lepc”, “limb”, “mathbold”, “mathdbl”, “mathmono”, “mathsanb”, “mathsans”, “mlym”, “modi”, “mong”, “mroo”, “mtei”, “mymr”, “mymrshan”, “mymrtlng”, “newa”, “nkoo”, “olck”, “orya”, “osma”, “rohg”, “saur”, “segment”, “shrd”, “sind”, “sinh”, “sora”, “sund”, “takr”, “talu”, “tamldec”, “telu”, “thai”, “tibt”, “tirh”, “vaii”, “wara”, “wcho”。numberingSystem属性默认值为locale的默认数字系统。
  • pluralFormat 复数字符串
    首先引入common模块
import common from '@ohos.app.ability.common';

调用getPluralStringValue,根据指定数量获取指定ID字符串表示的单复数字符串

getPluralString(id: number, num: number) {
    let context = getContext(this) as common.UIAbilityContext;
    let plural = await context.resourceManager.getPluralStringValue(id, num);
    return pluralFormat;
  }

resourceManager官方文档@ohos.resourceManager

  • timeZoneDetect
    调用getTimezonesByLocation创建某经纬度对应的时区对象数组
const LONGITUDE = 116.20;
const LATITUDE = 39.56;
getTimeZoneDetect() {
    this.timeZoneDetect = await ResourceUtil.getString($r('app.string.coordinate').id);
    this.timeZoneDetect += '(' + LONGITUDE + ',' + LATITUDE + ') ' +
      i18n.TimeZone.getTimezonesByLocation(LONGITUDE, LATITUDE)[0].getDisplayName();
  }
  • normalizer
    调用Normalizer.getInstance获取文本正则化对象
getNormalizer() {
    let nl = i18n.Normalizer.getInstance(i18n.NormalizerMode.NFC);
    this.normalizer = '\u1100 +\u1161 +\u11A8 = ' + nl.normalize('\u1100\u1161\u11A8');
  }
  • mDirection
    调用getDirection方法获取设备的配置,拿到屏幕方向属性
  async getDirection() {
  let context = getContext(this) as common.UIAbilityContext;
  let configuration = await context.resourceManager.getConfiguration();
  if (configuration.direction === 1) { // 1代表Horizontal,0代表Vertical
    return 'Horizontal';
  } else {
    return 'Vertical';
  }
}
}

#2023盲盒+码# OpenHarmony国际化I18n开发-鸿蒙开发者社区

参考资料

国际化应用示例
I18n开发指导
Intl开发指导
国际化开发概述

©著作权归作者所有,如需转载,请注明出处,否则将追究法律责任
标签
已于2023-9-3 23:31:04修改
1
收藏
回复
举报
回复
    相关推荐