Android 本地化

本文档介绍 Android SDK 的本地化功能,以及如何使用 Xamarin 访问它们。

Android 平台功能

本部分介绍 Android 的主要本地化功能。 跳到 下一部分 以查看特定代码和示例。

区域设置

用户选择其语言设置>语言和输入。 此选择控制所使用的语言和区域设置(例如,用于日期和数字格式)。

可以通过当前上下文的 Resources以下区域设置查询当前区域设置:

var lang = Resources.Configuration.Locale; // eg. "es_ES"

此值将是一个区域设置标识符,其中包含语言代码和区域设置代码,用下划线分隔。 有关参考,下面列出了通过 StackOverflow 的 Java 区域设置和 Android 支持的区域设置。

常见示例包括:

  • en_US英语(美国)
  • es_ES 西班牙语(西班牙)
  • ja_JP 日本语(日本)
  • zh_CN 中文(中国)
  • zh_TW 中文(台湾)
  • pt_PT 葡萄牙语(葡萄牙)
  • pt_BR 葡萄牙语(巴西)

LOCALE_CHANGED

当用户更改其语言选择时,Android 将 android.intent.action.LOCALE_CHANGED 生成。

活动可以通过在活动上设置 android:configChanges 属性来选择处理此功能,如下所示:

[Activity (Label = "@string/app_name", MainLauncher = true, Icon="@drawable/launcher",
    ConfigurationChanges = ConfigChanges.Locale | ConfigChanges.ScreenSize | ConfigChanges.Orientation)]

Android 中的国际化基础知识

Android 的本地化策略具有以下关键部分:

  • 要包含本地化字符串、图像和其他资源的资源文件夹。

  • GetText 方法,用于在代码中检索本地化字符串

  • @string/id 在 AXML 文件中,自动将本地化字符串放置在布局中。

资源文件夹

Android 应用程序管理资源文件夹中的大部分内容,例如:

  • layout - 包含 AXML 布局文件。
  • 绘制 - 包含图像和其他可绘制资源。
  • values - 包含字符串。
  • raw - 包含数据文件。

大多数开发人员已经熟悉在可绘制目录中使用 dpi 后缀来提供图像的多个版本,让 Android 为每个设备选择正确的版本。 同一机制用于通过用语言和区域性标识符后缀资源目录来提供多种语言翻译。

Screenshot of Resources/drawable and Resources/values folders for multiple cultural identifiers

注意

指定顶级语言(如 es 只需要两个字符);但是,指定完整区域设置时,目录名称格式需要短划线和小写 r 来分隔两个部分,例如 pt-rBRzh-rCN。 将此值与代码中返回的值进行比较,该值具有下划线(例如)。 pt_BR 这两者都不同于 .NET CultureInfo 类使用的值,它只具有短划线(例如)。 pt-BR 在跨 Xamarin 平台工作时,请记住这些差异。

Strings.xml 文件格式

本地化 目录(例如 values-esvalues-pt-rBR) 应包含名为 Strings.xml 的文件,该文件将包含该区域设置的已翻译文本。

每个可翻译字符串都是一个 XML 元素,其资源 ID 指定为 name 属性,转换后的字符串作为值:

<string name="app_name">TaskyL10n</string>

你需要根据正常的 XML 规则进行转义,并且 name 必须是有效的 Android 资源 ID(无空格或短划线)。 下面是示例的默认字符串文件示例:

values/Strings.xml

<resources>
    <string name="app_name">TaskyL10n</string>
    <string name="taskadd">Add Task</string>
    <string name="taskname">Name</string>
    <string name="tasknotes">Notes</string>
    <string name="taskdone">Done</string>
    <string name="taskcancel">Cancel</string>
</resources>

西班牙语目录 值 -es 包含具有相同名称(Strings.xml)的文件,其中包含翻译:

values-es/Strings.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string name="app_name">TaskyLeon</string>
    <string name="taskadd">agregar tarea</string>
    <string name="taskname">Nombre</string>
    <string name="tasknotes">Notas</string>
    <string name="taskdone">Completo</string>
    <string name="taskcancel">Cancelar</string>
</resources>

Screenshot of multiple values folders, each containing a Strings.xml file

设置字符串文件后,可以在布局和代码中引用翻译的值。

AXML 布局文件

若要在布局文件中引用本地化字符串,请使用 @string/id 语法。 此示例中的此 XML 代码片段显示 text 使用本地化资源 ID 设置的属性(已省略其他一些属性):

<TextView
    android:id="@+id/NameLabel"
    android:text="@string/taskname"
    ... />
<CheckBox
    android:id="@+id/chkDone"
    android:text="@string/taskdone"
    ... />

GetText 方法

若要在代码中检索翻译后的字符串,请使用 GetText 该方法并传递资源 ID:

var cancelText = Resources.GetText (Resource.String.taskcancel);

数量字符串

Android 字符串资源还允许创建 数量字符串 ,使翻译人员可以为不同的数量提供不同的翻译,例如:

  • “还有 1 个任务。
  • “还有 2 个任务要做。

(而不是泛型“有 n 个任务(s)左”)。

Strings.xml 中

<plurals name="numberOfTasks">
   <!--
      As a developer, you should always supply "one" and "other"
      strings. Your translators will know which strings are actually
      needed for their language.
    -->
   <item quantity="one">There is %d task left.</item>
   <item quantity="other">There are %d tasks still to do.</item>
 </plurals>

若要呈现完整的字符串,请使用 GetQuantityString 该方法,传递要显示的资源 ID 和值(两次传递)。 Android 使用第二个参数来确定quantity要使用的字符串,第三个参数是实际替换到字符串中的值(两者都需要)。

var translated = Resources.GetQuantityString (
                    Resource.Plurals.numberOfTasks, taskcount, taskcount);`

有效 quantity 开关包括:

  • 一个
  • 两种
  • few
  • 很多
  • 其他

Android 文档中更详细地介绍了它们。如果给定语言不需要“特殊”处理,则忽略这些quantity字符串(例如,仅one使用英语;other指定zero字符串将不起作用,不会使用)。

映像

本地化图像遵循与字符串文件相同的规则:应用程序中引用的所有图像都应放置在 绘制的目录中,以便有回退。

然后,应将特定于区域设置的图像放置在限定的可绘制文件夹中,例如 drawable-esdrawable-ja (也可以添加 dpi 说明符)。

在此屏幕截图中,四个图像保存在可绘制目录中,但只有一个 flag.png 已在其他目录中本地化副本。

Screenshot of multiple drawable folders, each containing one or more localized .png files

其他资源类型

还可以提供其他类型的替代、特定于语言的资源,包括布局、动画和原始文件。 这意味着可以为一种或多种目标语言提供特定的屏幕布局,例如,你可以专门为德语创建一个布局,该布局允许很长的文本标签。

如果设置应用程序设置android:supportsRtl="true",Android 4.2 引入了对从右到左(RTL)语言的支持。 资源限定符 "ldrtl" 可以包含在目录名称中,以包含专为 RTL 显示设计的自定义布局。

有关资源目录命名和回退的详细信息,请参阅 Android 文档来 提供替代资源

应用名称

应用程序名称可通过对活动使用 @string/id in MainLauncher 轻松本地化:

[Activity (Label = "@string/app_name", MainLauncher = true, Icon="@drawable/launcher",
    ConfigurationChanges =  ConfigChanges.Orientation | ConfigChanges.Locale)]

从右到左 (RTL) 语言

Android 4.2 及更新版为 RTL 布局提供完全支持,详述了 本机 RTL 支持博客

使用 Android 4.2(API 级别 17)及更新时,可以使用和end而不是leftright例如android:paddingStart)指定start对齐值。 还有一LayoutDirectionTextDirection些新的 API,用于TextAlignment帮助生成适合 RTL 阅读器的屏幕。

以下屏幕截图显示了 阿拉伯语中本地化 的 Tasky 示例

Screenshot of Tasky app in Arabic

下一个屏幕截图显示了 希伯来语中本地化 的 Tasky 示例

Screenshot of Tasky app in Hebrew

RTL 文本使用 Strings.xml 文件进行本地化,方式与 LTR 文本相同。

测试

请务必全面测试默认区域设置。 如果由于某种原因(即缺少默认资源),应用程序将崩溃。

模拟器测试

有关如何使用 ADB shell 将模拟器设置为特定区域设置的说明,请参阅 Android Emulator 上的 Google 测试部分。

adb shell setprop persist.sys.locale fr-CA;stop;sleep 5;start

设备测试

若要在设备上进行测试,请更改设置应用中的语言

提示

记下菜单项的图标和位置,以便你可以将语言还原到原始设置。

总结

本文介绍使用内置资源处理本地化 Android 应用程序的基础知识。 可在此跨平台指南了解有关 iOS、Android 和跨平台(包括 Xamarin.Forms)应用的 i18n 和 L10n 的详细信息。