Hello, L10N
本教程里,我们将创建Hello, L10N应用,利用Android框架来有选择的加载资源。我们通过在res/目录添加资源来将应用本地化。
本教程使用了Localization 文档里所讲的练习。
创建一个非本地化的应用
第一版的Hello, L10N应用将只使用默认资源目录 (res/drawable
, res/layout
, 和res/values
)。这些资源没有被本地化 -- 他们是我们在应用里最常用资源:图像、布局和字符串。当用户以默认语言和地区运行应用,或者设置的语言和地区应用没有特别支持,应用将从这些默认目录加载资源。
这个应用包含一个简单的用户界面,显示两个TextView对象和一个背景图片是国旗的图片按钮。点击按钮,会弹出一个AlertDialog来显示其余的文本。
创建项目和布局
这个应用里,默认语言是英式英语,默认地区是英国。
- 创建一个新的工程和Activity,名字叫 "HelloL10N" 。如果是在使用Eclipse,在新建Android工程向导里按下面的提示填写:
- Project name: HelloL10N
- Application name: Hello, L10N
- Package name: com.example.hellol10n (或者你自己的命名空间)
- Create Activity: HelloL10N
- Min SDK Version: 3
这个基础的工程包含一个res/目录,下面有子目录存放3种最常用类型的资源:图像(
res/drawable/
),布局(res/layout/
) 和字符串 (res/values/
)。后面将做的绝大部分的本地化工作就是向res/目录添加更多子目录。 - 打开
res/layout/main.xml
文件并修改如下:<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" > <TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:gravity="center_horizontal" android:text="@string/text_a" /> <TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:gravity="center_horizontal" android:text="@string/text_b" /> <Button android:id="@+id/flag_button" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" /> </LinearLayout>
LinearLayout包含两个TextView对象用于显示本地化文本和一个按钮用于显示国旗。
创建默认资源
布局文件里引用的资源需要定义。
- 创建默认文本字符串。打开文件
res/values/strings.xml
,修改如下: -
<?xml version="1.0" encoding="utf-8"?> <resources> <string name="app_name">Hello, L10N</string> <string name="text_a">Shall I compare thee to a summer"'"s day?</string> <string name="text_b">Thou art more lovely and more temperate.</string> <string name="dialog_title">No Localisation</string> <string name="dialog_text">This dialog box"'"s strings are not localised. For every locale, the text here will come from values/strings.xml.</string> </resources>
上面的XML代码定义了应用里用到的每一句英式英语。在将应用本地化的时候,我们将提供不同国家语言版本的替换字符串,包括德语、法语和日语。
- 在目录
res/drawable
下添加默认的国旗图案:保存flag.png 为res/drawable/flag.png
。当应用没有被本地化时,将会显示英国国旗。
- 打开文件HelloL10N.java,在onCreate()方法末尾添加以下内容:
// assign flag.png to the button, loading correct flag image for current locale Button b; (b = (Button)findViewById(R.id.flag_button)).setBackgroundDrawable(this.getResources().getDrawable(R.drawable.flag)); // build dialog box to display when user clicks the flag AlertDialog.Builder builder = new AlertDialog.Builder(this); builder.setMessage(R.string.dialog_text) .setCancelable(false) .setTitle(R.string.dialog_title) .setPositiveButton("Done", new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int id) { dialog.dismiss(); } }); final AlertDialog alert = builder.create(); // set click listener on the flag to show the dialog box b.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { alert.show(); } });
小贴士:在Eclipse里面,使用快捷键Ctrl-Shift-O (Cmd-Shift-O, 在Mac上)来自动导入当前源文件需要的包,然后保存源文件。
上面添加的代码功能如下:
- 将正确的国旗图标分配给按钮。现在,只定义了默认资源,所以而不管语言和地区是什么,这段代码总是分配
res/drawable/flag.png
(英国国旗)给按钮。一旦我们为不同地点添加更多的国旗,这段代码有时将会分配一个不同的国旗。 - 创建了一个
AlertDialog
,并设置了点击事件监听器,所以当用户点击按钮时将弹出一个报警对话框。我们还没有本地化对话框的内容,所以对话框总是显示res/values/strings.xml里面定义的dialog_text的值。
- 将正确的国旗图标分配给按钮。现在,只定义了默认资源,所以而不管语言和地区是什么,这段代码总是分配
工程结构如下(译者注:截图里面的HelloLocalization.java应该改为:HelloL10N.java):

小贴士: 如果你想在手机设备上而不是仅仅在模拟器上运行应用,打开AndroidManifest.xml
文件并在<application>
节点添加android:debuggable="true"。 关于如何设置手机设备让它能够运行你开发的应用,请参考Developing on a Device.
运行这个未本地化的应用
保存工程并运行应用,看看它是怎么工作的。不管你怎么设置手机设备或者模拟器的语言和地区,应用显示的内容完全一样,内容如下:
非本地化应用, 运行在任何语言和地区: | 点击国旗后,任何语言和地区下: |
---|---|
![]() | ![]() |
规划本地化
本地化一款应用的第一步是规划应用在不同的语言地区显示的内容有什么不同。这款应用里,默认地点是英国。我们将为德国、法国、加拿大、日本和美国添加一些地点相关的信息。表1列出了应用在不同的地点将显示的内容。
表1
地区/语言 | 英国 | 德国 | 法国 | 加拿大 | 日本 | 美国 | 其他 |
---|---|---|---|---|---|---|---|
英语 | 英式英语文本; 英国国旗(默认) | - | - | 英式英语文本; 加拿大国旗 | - | 英式英语文本; 美国国旗 | 英式英语文本;英国国旗(默认) |
德语 | - | 德语文本:app_name ,text_a 和text_b ; 德国国国旗 | - | - | - | - | 德语文本:app_name ,text_a 和text_b ; 英国国旗 |
法语 | - | - | 法语文本app_name ,text_a 和text_b ; 法国国旗 | 法语文本:app_name ,text_a 和text_b ; 加拿大国旗 | - | - | 法语文本:app_name ,text_a 和text_b ; 英国国旗 |
日语 | - | - | - | - | 日语文本:text_a and text_b ; 日本国旗 | - | 日语文本: text_a andtext_b ; 英国国旗 |
其他语言 | - | - | - | - | - | - | 英式英语文本;英国国旗(默认) |
注意,其他行为也是可能的;例如,应用里可以支持加拿大英语或者美式英语。但是添加了这几段英语文本以后,增加的英语版本并不能让应用显得更有用。
如上表所示,除了已保存在目录res/drawable/
下面的英国国旗,添加了另外5个国旗图标,还添加了res/values/strings.xml
里所定义文本以外的3组字符串文本。
表2显示添加的字符串文本和国旗图标应该放在哪些目录下,并指定了哪个语言和地区将加载哪些内容。(想知道更多的语言和地区编码,请参考Alternate Resources.)
表 2
语言和地区编码 | 语言 / 国家 | strings.xml位置 | flag.png位置 |
---|---|---|---|
默认 | 英语 / 英国 | res/values/ | res/drawable/ |
de-rDE | 德语/ 德国 | res/values-de/ | res/drawable-de-rDE/ |
fr-rFR | 法语/ 法国 | res/values-fr/ | res/drawable-fr-rFR/ |
fr-rCA | 法语 / 加拿大 | res/values-fr/ | res/drawable-fr-rCA/ |
en-rCA | 英语/ 加拿大 | (res/values/) | res/drawable-en-rCA/ |
ja-rJP | 日语/ 日本 | res/values-ja/ | res/drawable-ja-rJP/ |
en-rUS | 英语/ 美国 | (res/values/) | res/drawable-en-rUS/ |
小贴士: 一个目录名限定符不能只指定地区而不指定语言。例如,如果一个目录名是res/drawable-rCA/
,编译将会出错。
在运行期间,应用将根据用户手机设备里设置的语言和地区来加载对应的一组资源。如果指定语言和地区相关的资源不存在,就加载默认资源。
例如,假设手机设备的语言设置为德语,而地点被设置为瑞士。因为应用中没有国旗文件res/drawable-de-rCH/flag.png,系统将加载默认的英国国旗res/drawable/flag.png
。使用的语言将是德语。向在瑞士讲德语的人展示一幅英国国旗是很不理想的,但现在我们保持这种行为就是了。如果你想改进应用的行为,有好几种方法可以做到:
- 使用一般的默认图标。这款应用里,可以用莎士比亚的照片。
- 创建一个目录
res/drawable-de/
放置一个图标,无论何时语言被设置为德语而地点不是德国的时候,应用将使用这个图标。
将应用本地化
将字符串本地化
这款应用需要增加3个strings.xml
文件,德语、法语、日语各一个。在Eclipse里面添加这3个资源文件的步骤如下:
- 选择File > New > Android XML File 打开新建Android XML文件向导。你也可以在工具栏点击向导图标来打开向导:
- 选择工程HelloL10N,并输入文件名strings.xml。在左侧的列表里面,选择Language,然后点击右箭头。
- 在语言框里输入de并点击结束。
一个新的文件
res/values-de/strings.xml
现在就出现在工程里面了。 - 重复上面的步骤为语言编码fr和ja创建两个资源文件。现在,工程包括了以下3个新的骨架文件:
res/values-de/strings.xml
res/values-fr/strings.xml
res/values-ja/strings.xml
- 在新文件里添加本地化的文本。打开
res/values-<qualifier>/strings.xml
,并将内容修改如下:
文件 | 修改内容如下: |
---|---|
res/values-de/strings.xml |
|
res/values-fr/strings.xml |
|
res/values-ja/strings.xml |
|
小贴士: 在values-<qualifier>/strings.xml
文件里, 只需要包括跟默认字符串不同的文本。例如,当应用在一个设置为日语的手机设备上运行时,计划是text_a和text_b显示日文,而其他文本显示英文,因此res/values-ja/strings.xml
只需要包含text_a
和 text_b
。
将图片本地化
如表2所示,需要增加6个图像目录,每个目录都包含一个flag.png图标。为你的工程添加需要的图标和目录:
- 保存这个德国国旗 为
res/drawable-de-rDE/flag.png
。
例如:
- 点击链接打开国旗图片。
- 保存图片到目录
your-workspace/HelloL10N/res/drawable-de-rDE/
下。
- 保存法国国旗 为
res/drawable-fr-rFR/flag.png
- 保存加拿大国旗为
res/drawable-fr-rCA/flag.png
- 再次保存 加拿大国旗为
res/drawable-en-rCA/flag.png
。 (为什么这次不是只有一个目录包含加拿大国旗?因为一个目录限定符不能只设置地区而不设置语言。你不能创建一个名为drawable-rCA/
的目录;相反,必须创建两个分开的目录,分别对应两种加拿大语言。) - 保存 日本国旗 为
res/drawable-ja-rJP/flag.png
。 - 保存美国国旗 为
res/drawable-en-rUS/flag.png
。
如果使用的是Eclipse,请刷新下面(按F5)。新添加的res/drawable-<qualifier>/
目录应该显示在工程里了。
运行并测试本地化应用
一旦添加了本地化的字符串和图像资源,就可以运行应用并测试应用如何加载资源了。使用设置应用(主屏> 菜单 > 设置 > 位置和文本 > 选择位置)来更改手机设备或者模拟器的地点。
设置模拟器的语言和地点为应用没有特别支持的,使用Custom Locale应用,在Application一栏:
长按一个语言和地区名字就能转换为这个语言和地区。
想要一个不同版本Android平台支持的语言和地点列表,请参考平台说明文档,被列在SDK一栏“可下载SDK组件”下面。例如: Android 2.0 locales.
运行应用,设置预期的语言和地区,外加一个超出预期的语言和地区,下面是可能看到结果:
语言和地区 | 应用显示内容 |
---|---|
德语/ 德国 Hello, L10N应用特别支持。 | ![]() |
法语/ 加拿大 Hello, L10N应用特别支持。 | ![]() |
德语/ 瑞士 只有语言被Hello, L10N应用特别支持。 | ![]() |
日语 Hello, L10N应用特别支持。 | ![]() |
罗曼语 / 瑞士 (自定制语言和地区 rm_CH ) Hello, L10N应用没有特别支持,因此使用默认资源。 | ![]() |
转载请注明出处:http://blog.youkuaiyun.com/mtding/article/details/7017945