Android 语言国际化
2015-06-17 20:02
441 查看
前言
我们在使用Android手机系统的时候经常在“设置”项里面会提供用户多种系统语言选择,比如:中文、英语…… 大家或许已经发现这些语言显示顺序都是“从左往右”;但是有一些语言是“从右往左”显示的,比如阿拉伯语、希伯来语等语言,当在这种语言环境下时,我们需要怎么来处理布局文件呢?接下来的时间我们就来讨论处理阿拉伯语等“从右往左”显示语言的问题。布局
首先我们先讲解布局问题,在Android系统中为了支持不同语言显示,可以定义特定(阿拉伯语、希伯来语……)语言布局文件,具体如图所示:
图中layout-ar对应的就是阿拉伯语的布局文件,因此我们只需要修改该目录下的布局文件,就可以实现我们在阿拉伯语言环境中的现实效果。在Android4.2之前,我们需要对每一种“从右往左”显示的语言copy一份布局文件进行修改,如图中layout-fa layout-iw等,这样做的缺点就是会产生许多冗余布局文件。
Android4.2版本之后,Google针对阿拉伯等bidi语言(备注:bidi语言即“从右往左”书写的语言)view和文字布局文件做了重大修改,类似2D图形加速机制,可以从Activity/Application控制、Window代码控制、View资源控制共3个级别的控制。所有关于bidi语言的布局文件都可以放在layout-ldrtl目录,如图所示:
layout-ldrtl是Google专门为bidi语言预留的布局目录,所以在Android4.2版本之后,layout-fa layout-iw等目录可以直接删除,只需要在layout-ldrtl目录下定义bidi语言布局即可。
Activity/Application控制
在Manifest文件中我们可以设置android:supportsRtl属性,具体请参考如下代码:
[html]
view plaincopy
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme"
android:supportsRtl="true" >
View控制
在layout-ldrtl目录的布局文件中设置android:layoutDirection属性,具体请参考如下代码:
[html]
view plaincopy
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layoutDirection="rtl" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/hello_world"
android:layoutDirection="rtl" />
</LinearLayout>
备注:layout-ldrtl优先级介绍,layout-ldrtl优先级要低于语言级别(layout-ar),因此如果存在layout-ar目录,会首先去查找layout-ar目录下的布局文件,因此建议删除layout-ar等bidi语言目录。layout-ldrtl优先级又高于分辨率等级,优先级归纳如下:
layout-ar(语言级别) > layout-ldrtl > layout-800*540(分辨率)
代码控制
介绍了以上两种静态的控制方式后,我们再来看看动态控制bidi语言显示方式,具体请参考如下代码:
[java]
view plaincopy
if ("ar".equals(Locale.getDefault().getLanguage())) {
getWindow().getDecorView().setLayoutDirection(View.LAYOUT_DIRECTION_RTL);
}
以上就是bidi语言涉及的布局修改及配置方式,组合使用以上几种方式便可以解决我们在国际化中遇到的bidi语言问题。
HashCode
当大家阅读到这儿的时候,可能会存在疑问,Hashcode和语言会有什么关系呢?其实Hashcode问题才是最终决定我写这篇博客的目的。说到Hashcaode我们先来回忆一下Java中hashcode的作用,简单的说hashcode就是标识对象的唯一标识(备注:非严谨的说法)。最近在开发Android系统开发中遇到这样一个问题,当手机拍照后正常显示(图标显示Camera图标)应该如图1-1所示:
图1-1 图1-2
但是在Azeri和Turkish语言环境中却显示成了文件夹图标,如下图1-2所示,经过调查最终发现是以下代码在不同语言环境下Hashcode不同造成的,具体代码如下所示:
[java]
view plaincopy
public static int getBucketId(String path) {
return path.toLowerCase().hashCode();
}
按照以下方式更改后就能正常显示,具体代码如下:
[java]
view plaincopy
public static int getBucketId(String path) {
return path.toLowerCase(Locale.ENGLISH).hashCode();//使用英语字符转换
}
Android的解释信息如下:
Converts this string to lower case, using the rules of locale.
Most case mappings are unaffected by the language of a Locale. Exceptions include dotted and dotless I in Azeri and Turkish locales, and dotted and dotless I and J in Lithuanian locales. On the other hand, it isn't necessary to provide a Greek locale to get
correct case mapping of Greek characters: any locale will do.
大概意思就是阿塞拜疆和土耳其语言环境中使用的字符编码不一样,我们必须将字符编码设置成统一的本地编码这样Hashcode才保持一致
具体编码请参考:http://www.unicode.org/Public/UNIDATA/SpecialCasing.txt
总结:Android语言国际化就总结这么多,希望对大家有所助力;大家如果对语言国际化有新的见解或者更好的实现方式,请在commit中评论,我们共同讨论。
相关文章推荐
- Android中继承RadioButton后,点击不能选中
- Android 自定义视图
- android进度条
- Android学习路径(十)如何将Action Bar堆放在布局
- ROOT android 原则。 基于(zergRush)
- Android学习笔记——menu
- android坐标2
- Android学习笔记——LinearLayout
- Android学习笔记——MixLayout
- Android 拼图游戏知识点小结
- 2015-06-16
- 2015-06-15
- Android学习笔记——TableLayout
- 5.28
- [笔记] Android NDK 开发笔记
- android_sharedpreference的使用
- android listview局部刷新和模拟应用下载
- android 基于Substrate框架的Hook
- Android Activity life Cycle
- 【Android笔记】MediaPlayer基本用法