@nativescript/localize
利用每个平台的原生能力为 NativeScript 提供的国际化(i18n)插件。
npm i --save @nativescript/localize

@nativescript/localize

内容

简介

一个实现国际化的插件(i18n),利用每个平台的原生能力。它受到 nativescript-i18n 的启发。

安装

要安装插件,请在项目的根目录中运行以下命令。

npm install @nativescript/localize

使用 @nativescript/localize

本节描述了如何使用 NativeScript 支持的多种方式使用 @nativescript/localize 插件。

NativeScript 核心的国际化

  1. app 文件夹中创建一个名为 i18n 的文件夹,具有以下结构
app
| i18n
| en.json <-- english language
| es.default.json <-- spanish language (default)

es.default.json 示例

{
"app.name" : "Comida Rica!",

"user":{
"name": "Paula"
}
}
  1. main.ts 文件中,使用以下方式将 localize 函数注册到 Appilcation 类的 setResources 方法。
import { Application } from "@nativescript/core";
import { localize } from '@nativescript/localize';

Application.setResources({ L: localize });

然后,在标记中使用 L 属性。


<StackLayout>
<Label text="{{ 'Hello world !' | L }}" />
<Label text="{{ 'I am ' + L('user.name') }}" />
</StackLayout>

在代码后面进行本地化,只需直接调用 localize 方法。

import { localize } from '@nativescript/localize';

console.log(localize('Hello world !'));

注意事项

⚠️ 如果您注意到翻译在主 XML 页面上工作,但在导航到的页面上不工作,则请将此小技巧添加到新页面的 '页面加载' 函数中

const page = args.object;
page.bindingContext = new Observable();

Angular 中的国际化

  1. src 文件夹中创建一个名为 i18n 的文件夹,具有以下结构
src
| i18n
| en.json <-- english language
| fr.default.json <-- french language (default)
| es.js

您需要 设置默认语言 并确保它包含 应用名称 以避免任何错误。

  1. app.module.ts 文件中注册本地化模块(NativeScriptLocalizeModule
import { NgModule, NO_ERRORS_SCHEMA } from '@angular/core';
import { NativeScriptLocalizeModule } from '@nativescript/localize/angular';
import { NativeScriptModule } from '@nativescript/angular';

import { AppComponent } from './app.component';

@NgModule({
declarations: [AppComponent],
bootstrap: [AppComponent],
imports: [NativeScriptModule, NativeScriptLocalizeModule],
schemas: [NO_ERRORS_SCHEMA],
})
export class AppModule {}
  1. 然后,在 HTML 文件中按以下方式使用本地化器
<Label text="{{ 'Hello world !' | L }}"/>
<Label text="{{ 'I am %s' | L:'user name' }}"/>

Vue 中的国际化

  1. app 文件夹中创建一个名为 i18n 的文件夹,具有以下结构
app
| i18n
| en.json <-- english language
| es.default.json <-- spanish language (default)

es.default.json 示例

{
"app.name" : "Comida Rica!",

"user":{
"name": "Paula"
}
}
  1. 要在 Vue3 中进行本地化,导入 localize 方法并在标记中调用它。
import { localize } from '@nativescript/localize';
<ActionBar>
<Label :text="localize('app.name')" class="font-bold text-lg bg-black" />
</ActionBar>

<StackLayout class="px-4">
<Label :text="localize('user.name')" textWrap="true" />
</StackLayout>

Svelte 中的国际化

  1. app 文件夹中创建一个名为 i18n 的文件夹,具有以下结构
app
| i18n
| en.json <-- english language
| es.default.json <-- spanish language (default)

es.default.json 示例

{
"app.name" : "Comida Rica!",

"user":{
"name": "Paula"
}
}
  1. 要在 Svelte 中进行本地化,导入 localize 方法并在标记中调用它。
import { localize } from '@nativescript/localize';
<actionBar>
<label text={ localize('app.name') } class="font-bold text-lg bg-black" />
</actionBar>

<stackLayout class="px-4">
<label text={ 'Nombre: ' + localize('user.name')}/>
</stackLayout>

设置默认语言

要设置默认语言,请将默认语言文件的名称添加 .default 扩展名。

fr.default.json

确保它包含 应用名称 以避免任何错误。

Android 使用与设备语言对应的区域文件。例如,如果设备的语言设置为 西班牙语,则将使用 es.json

本地化应用名称

要本地化应用名称,请使用 app.name 键。

{
"app.name": "My app"
}

文件格式

每个文件都是使用 require 导入的,因此请使用您选择的文件格式

JSON

{
"app.name": "My app",
"ios.info.plist": {
"NSLocationWhenInUseUsageDescription": "This will be added to InfoPlist.strings"
},
"user": {
"name": "user.name",
"email": "user.email"
},
"array": ["split the translation into ", "multiples lines"],
"sprintf": "format me %s",
"sprintf with numbered placeholders": "format me %2$s one more time %1$s"
}

JavaScript

export const i18n = {
'app.name': 'My app',
};

本地化 iOS 属性

要本地化 iOS 属性,请使用 ios.info.plist. 前缀。以下示例显示了如何本地化 NSLocationWhenInUseUsageDescription 属性。

{
"ios.info.plist.NSLocationWhenInUseUsageDescription": "This will be added to InfoPlist.strings"
}

在运行时动态更改语言

要动态地在运行时更改语言,请使用 overrideLocale 方法。

iOS

import { overrideLocale } from '@nativescript/localize';
const localeOverriddenSuccessfully = overrideLocale('en-GB'); // or "nl-NL", etc (or even just the part before the hyphen)

Android

对于Android,首先在 main.ts 文件中调用 launchEvent 处理器中的 androidLaunchEventLocalizationHandler 方法。

import { Application } from '@nativescript/core';
import { androidLaunchEventLocalizationHandler } from '@nativescript/localize';

Application.on(Application.launchEvent, (args) => {
if (args.android) {
androidLaunchEventLocalizationHandler();
}
});

然后,在用户选择语言的设置页面中调用 overrideLocale 方法。

import { overrideLocale } from '@nativescript/localize';
const localeOverriddenSuccessfully = overrideLocale('en-GB'); // or "nl-NL", etc (or even just the part before the hyphen)

重要:在两个平台上,调用 overrideLocale 方法后,您必须要求用户重新启动应用程序。

例如:

import { Application } from '@nativescript/core';
import { overrideLocale } from '@nativescript/localize';

alert({
title: 'Switch Language',
message: 'The application needs to be restarted to change language',
okButtonText: 'Quit!',
}).then(() => {
L.localize.overrideLocale(selectedLang);
if (isAndroid) {
(Application.android.foregroundActivity || Application.android.startActivity).finish();
} else {
exit(0);
}
});

重要:如果您正在使用 Android App Bundle 发布您的Android应用程序,请将以下内容添加到 App_Resources/Android/app.gradle 中,以确保所有语言都包含在拆分APK中:

android {

// there maybe other code here //

bundle {
language {
enableSplit = false
}
}
}

提示:您可以通过 Device 类的 language 属性获取用户手机上的默认语言。

import { Device } from '@nativescript/core';

console.log("user's language is", Device.language.split('-')[0]);

提示: overrideLocale 方法将语言存储在应用程序设置的特殊键中,您可以通过以下方式访问它

import { ApplicationSettings } from '@nativescript/core';

console.log(ApplicationSettings.getString('__app__language__')); // only available after the first time you use overrideLocale(langName);

故障排除

Angular 本地化管道和模态上下文

当在模态上下文中时,Angular本地化管道不起作用。作为一种解决方案,您可以在组件构造函数中触发变更检测。

constructor(
private readonly params: ModalDialogParams,
private readonly changeDetectorRef: ChangeDetectorRef,
) {
setTimeout(() => this.changeDetectorRef.detectChanges(), 0);
}

Android N+ 上的 WebView 问题

在Android N+上,WebView的首次创建会将应用程序区域设置重置为设备默认设置。因此,您必须设置所需的区域设置。这是一个原生错误,解决方案如下:

 <WebView url="https://someurl.com" @loaded="webViewLoaded"/>
import { overrideLocale, androidLaunchEventLocalizationHandler } from '@nativescript/localize';
import { ApplicationSettings } from '@nativescript/core';
const locale = ApplicationSettings.getString('__app__language__');

function webViewLoaded() {
overrideLocale(locale);
androidLaunchEventLocalizationHandler();
}

API

该插件提供了以下功能。

localize()

localizeString: string = localize(key, ...args)

i18n 目录中的 .json 文件中检索指定 key 的翻译。


overrideLocale()

isLocaleOverwritten: boolean = overrideLocale(locale)

使用指定的 locale 参数覆盖当前区域设置。


androidLaunchEventLocalizationHandler()

androidLaunchEventLocalizationHandler()

鸣谢

对于过去开发并维护此插件 Ludovic Fabrèges (@lfabreges) 的努力,我们表示衷心的感谢。当他因优先级调整而不得不放弃该项目时,他非常慷慨地将仓库 迁移给我。此后,Eddy 加入到 NativeScript 的技术指导委员会,并通过以下方式大大提高了插件维护工作:对其进行范围界定并迁移至此

许可证

Apache License Version 2.0