第九章 多语言环境的支持和多屏幕的适配(1)

第九章 多语言环境的支持和多屏幕的适配

资源是在代码中使用到的,并且在编译时被打包进应用程序的附加文件。出于加载效率的考虑,资源被从代码中分离出来,而且XML文件被编译进二进制代码中。在Android中,程序代码可以不直接和资源发生关系,而是通过R文件提供的索引来间接的引用某一个资源。Android系统会自动根据用户当前的环境,和屏幕分辨率情况,自动选用最合适的资源。正是基于Android系统这种独特的处理方式,开发者可以编写多套资源文件,从而很方便的实现多语言环境的支持和多种屏幕的适配。

本章将详细说明Android程序的资源的结构,以及具体如何适配多语言环境和多种屏幕。

9.1Android程序的资源文件

9.1.1资源文件的目录结构

资源是外部文件(即非代码文件),它在代码中被使用,是在编译的时候加载到应用程序的。Android支持很多种不同类型的资源文件,包括XML、PNG和JPEG等文件。在Eclipse的工程中,res目录有默认几项resource,比如:

1)res/drawable/---图像类型的资源文件。

2)res/layout/---可被编译成屏幕布局(部分布局)的XML文件。

3)res/values/---可被编译成多种类型的资源的XML文件。文件可以被命名为任何名字,这个文件夹有一些经典的文件(一般约定以文件中定义的元素名称来给文件命名):

  • arrays.xml定义数组。
  • colors.xml定义颜色和颜色字符串值。分别用Resources.getDrawable()和Resources.getColor()方法获取这些资源。
  • dimens.xml定义尺寸数据,可以用Resources.getDimension()方法取得这些资源。
  • strings.xml定义字符串值,可以用Resources.getString()或者Resources.getText()方法来获取这些资源。其中getText()方法将保留任何丰富的通常在UI中描述的文字样式。)
  • styles.xml定义样式对象。

4)res/menu/---菜单对象的XML文件,可以通过重载Activity类的onCreateOptionsMenu()方法,使用“MenuInflaterinflater = getMenuInflater(); inflater.inflate(R.menu.menu,menu; ”代码片段来获取。

5)res/anim/---XML文件,被编译成逐帧动画或者是补间动画的对象。

6)res/xml/---用来放置style、theme等xml文件的定义。也可放置任何XML文件,在运行时可通过Resources.getXML()方法读取。

7)res/raw/---存放任何被直接拷贝到设备上的文件。在程序被编译时,它们直接加到压缩文件中。在应用程序中可以通过用Resources.openRawResource(id)方法来获取资源,id的形式为:R.raw.filename。

所有资源都会被编译到最终的APK文件里。Android会自动创建一个类——R.java,这样你在代码中可以通过它关联到对应的资源文件。R.java中包含的子类的命名由资源的路径和文件的名称决定。


经验分享:

上述res/values/目录下的文件命名(arrays.xml、colors.xml等等)只是Android官方推荐的名称。实际上,无论文件如何命名,比如命名为my.xml,也都是可以的。

另外,如果项目工程较大,包含很多的模块,就可以考虑以模块化的方式配置资源文件。比如整个项目用到的字符串,可以根据模块划分,命名为“模块1简称_strings.xml”、“模块2简称_strings.xml”等等,这样方便以后的维护。

9.1.2 资源文件目录的修饰语

Android通过检测硬件和语言的设置,去加载特定的资源文件。用户可以在系统的设置中设置系统的语言。为了包含各种替代资源,需要在同一目录下创建并行的文件夹,并且在每个文件夹名字后面加上相应的指定,说明它使用的配置(如语言,屏幕的方向等等)。例如,下面是一个工程中包含一个字符串资源,一个是英文版的,一个是法文版的:


res/

---->values-en/

--------------->strings.xml

----->values-fr/

--------------->strings.xml

当Android检测到系统语言为英文的时候,就会自动去查找资源文件中最符合的资源来给代码调用,这里将会调用values-en/strings.xml,而当系统语言为法文的时候,则会调用values-fr/strings.xml。

既然存在多种替代资源,这里就会有Android加载资源文件的步骤的问题。所有的资源文件名都可以加上一个或多个修饰语,在调用资源的时候,系统通过检测硬件和语言的设置一层一层的筛选,找出最匹配的资源返回。Android系统支持很多种不同类型的修饰语,把修饰语加在资源文件夹名字的后面,通过破折号隔开。并可以将多个修饰语加在文件夹的后面,但是它们必须按照规定的顺序出现。例如,一个文件夹包含图像资源,并且完全指定出所有配置,如下所示:


res/drawable-en-rUS-port-160dpi-finger-keysexposed-qwerty-dpad-480x320/

当然,你可以只指定一部分配置项,而将其他修饰语删除掉,只要将剩下的修饰语保留正确的顺序就可以。

下面我们按照顺序来对这些修饰语进行详细说明,请参考表9-1。


修饰语



语言


两个小写字母参照ISO639-1 标准。例如:en,fr,es


地区


一个小写字母加两个大写字母,参照ISO3166-1-alpha-2 标准。

例如:rUS,rFR,rES


屏幕方向


Port(竖屏),land(横屏),square


屏幕像素


92dpi,108dpi,等等


触摸屏类型


Notouch(不支持触屏),stylus(手写笔),finger(手指触摸)


键盘是否可用


Keysexposed(可用),keyshidden(不可用)


文本输入模式


Nokeys(无键盘),qwerty(标准传统键盘),12key(12个键)


导航模式


Nonav,dpad,trackball,wheel


屏幕分辨率


320×240,800×480,等等。大分辨率需要开始声明。

表9-1资源文件目录的修饰语

上面的这个列表,不包含设备的特殊参数,如载体、商标、设备/硬件、制造商。任何应用程序需要知道的设备信息,都在上面表格中的资源修饰语里。

下面是一些通用的关于资源目录的命名规范:

  • 各个变量用破折号分开(每个基本的目录名后跟一个破折号)
  • 变量是区分大小写的(所有变量名的大小写必须保持一致)

例如,一个drawable的目录必须命名为drawable-port,而不是drawable-PORT。

  • 你不能有两个目录命名为drawable-port和drawable-PORT,即使故意将“port”和“PORT”指向不同的参数值。
  • 同一类型的修饰语在一个文件名中只能出现一次(你不能这样命名drawable-rENrFR)
  • 你可以指定多个参数来定义具体的配置,但参数必须保持上面表格中的顺序。例如,drawable-en-rUS-land指在US-English的设备上使用。
  • Android会试图找到最适合当前配置的目录,关于这一点将在下面详细讲述
  • 表格里所有的参数的顺序是用来防止多个合格目录的事件发生(可看下面的例子)
  • 所有的目录,无论是否合格,都是放在res/目录下的。合格的目录是不能嵌套的(你不能这样写res/drawable/drawable-en)
  • 所有的资源将在代码或简单的资源引用语法,不加修饰的名字。因此,如果一个资源被命名为:

res/drawable-port-92dp/myimage.png

那么它可以这样被引用:

R.drawable.myimage(在代码中)

@drawable/myimage(在XML文件中)

9.1.3 程序加载资源文件的步骤

既然有如此繁多的资源文件,那么我们如何来对他们进行分类,并且做到国际化和本地化呢?这里,我们就必须先了解Android加载资源文件的步骤。

Android将挑选哪些资源文件在运行时会被使用,这取决于当前的配置。选择过程如下:

1)先找出包含匹配的资源的所有文件夹。

比如我们用到了资源myimage.png,而有下面的四个文件夹都包含这个资源。


res/drawable/myimage.png

res/drawable-en/myimage.png

res/drawable-port/myimage.png

res/drawable-port-92dpi/myimage.png

2)然后清除所有的不符合当前设备配置的资源。

例如,如果当前屏幕的像素是108dpi,那么将清除res/drawable-port-92dpi/。剩余下面的目录。


res/drawable/myimage.png

res/drawable-en/myimage.png

res/drawable-port/myimage.png

当前语言是en-GB,屏幕方向是port,那么有两个符合配置的选项:res/drawable-en/和res/drawable-port/,目录res/drawable/将被清除,因为它和当前的配置有0个属性相同,而其他两个文件有一个和配置文件相同的属性。此时剩余下面的目录。


res/drawable-en/myimage.png

res/drawable-port/myimage.png

3)如果还有多个目录存在,则根据配置的优先级选取最终的资源文件。

上面表格的修饰语就是按照优先级来写的。也就是说,语言的优先级比屏幕方向的优先级高,所以在这个例子中,我们会通过语言环境来优先选择res/drawable-en/目录。最终只剩下下面的目录,系统会在此目录下选择文件。


res/drawable-en/myimage.png

9.2国际化和本地化的支持

Internationalization(国际化)简称i18n,因为在i和n之间还有18个字符。Localization(本地化),简称L10n。国际化和本地化有一个通用的标准,一般的,在说明一个地区的语言时,用“语言_地区”的形式,比如zh_CN、zh_TW等等。

Android系统对i18n和L10n提供了非常好的支持。Android没有专门的API来提供国际化,而是通过对不同resource的命名来达到国际化的目的。同时,这种命名方法还可用于对硬件的区分,比如不同的新视屏,使用不同的图片资源。

下面的章节会详细的进行说明。

比如有两个string.xml的资源文件,分别在res\values目录下和res\values-zh目录下。

res\values\string.xml


<?xmlversion="1.0" encoding="utf-8"?>

<resources>

<stringname="hello">Hello, Test!</string>

</resources>

res\values-zh\string.xml


<?xmlversion="1.0" encoding="utf-8"?>

<resources>

<stringname="hello">你好,测试</string>

</resources>

在代码中调用:


Stringhello = getResources().getStringArray(R.string.hello);

如果系统的语言是中文的情况下,hello的值是“你好,测试”;在其它情况下,hello的值是“Hello,Test!”。

从以上的示例可以看到,只要简单的通过对资源目录进行适当的命名,就可以实现应用程序的国际化。


经验分享:

需要国际化的内容,一般包括所有文字信息(包括带有文字的图片)。

一般的,在实际项目中,国际化的工作是另外一个团队完成的。所以,开发人员在开发过程中,务必不要在代码中直接硬编码可能需要国际化的内容,而是将这些内容统统都写到资源文件中,在代码中通过资源的ID进行引用。这样,国际化团队只需要对部分资源文件进行国际化即可。

国际化过程还有一个难点是,国际化以后,由于不同语言的字符长度串不同,UI布局可能有所改变,这就需要国际化以后仔细的进行测试。

时间: 2024-10-08 09:45:02

第九章 多语言环境的支持和多屏幕的适配(1)的相关文章

第九章 多语言环境的支持和多屏幕的适配(2)

9.3多屏幕的适配 9.3.1屏幕参数的基本概念 Android手机屏幕大小不一,有480x320.640x360.800x480等等,还包括不同屏幕密度,怎样才能让应用程序自动适应不同的屏幕呢? 首先我们来了解几个基本概念: 1)屏幕尺寸Screensize 即显示屏幕的实际大小,按照屏幕的对角线进行测量. 为简单起见,Android把所有的屏幕大小分为四种尺寸:小.普通.大.超大(分别对应:small.normal.large.extralarge). 应用程序可以为这四种尺寸分别提供不同的

第九章 C语言在嵌入式中的应用

上章回顾 编码的规范和程序版式 版权管理和申明 头文件结构和作用 程序命名 程序注释和代码布局规范 assert断言函数的应用 与0或NULL值的比较 内存的分配和释放细节,避免内存泄露 常量特性 [email protected]:Kevin-Dfg/[email protected]:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.git 第九章 第九章 C语言在嵌入式中的应用 C语言在嵌入式中的应用 [email protecte

《数据结构与算法分析:C语言描述》复习——第九章“图论”——无权值的最短路径问题

2014.07.04 18:24 简介: 给定一个有向图,你可以认为每条边长度都是1(所以叫无权值).下面的算法可以求出从特定的起点到终点的最短路径长度. 描述: 从起点出发,根据当前顶点出发的边进行广度优先搜索,直至找到终点即可.如果搜索结束了仍然没有找到终点,那么起点无法到达终点. 实现: 1 // A simple illustration for unweighted shortest path. Graph represented by adjacency matrix. 2 #inc

第九章、shell脚本编程基础

第九章.shell脚本编程基础 本章内容 编程基础 脚本基本格式 变量 运算 条件测试 配置用户环境 编程基础 程序:指令+数据 程序编程风格: 过程式:以指令为中心,数据服务于指令 对象式:以数据为中心,指令服务于数据 shell程序:提供了编程能力,解释执行 程序的执行方式 计算机:运行二进制指令 编程语言: 低级:汇编 高级: 编译:高级语言-->编译器-->目标代码 java,C# 解释:高级语言-->解释器-->机器代码 shell, perl, python (系统后台

第九章 常用模块

第九章 常用模块 1.模块介绍 什么是模块: 模块就是我们通常说的py文件(因此写python程序的时候不要命名为模块的名称),模块是写好了但不直接使用的功能 为什么这些模块中提供的方法 不能像print这些内置函数一样直接使用呢? 是因为如果所有的模块都是执行python程序直接导入了,会非常占用内存空间的 常见导入模块的方法 1.import time 2.from time import sleep 模块的分类: 内置模块 扩展模块 https://pypi.org 自定义模块 2.扩展数

第九章: 输入与输出

@font-face{ font-family:"Times New Roman"; } @font-face{ font-family:"宋体"; } @font-face{ font-family:"Arial"; } @font-face{ font-family:"黑体"; } @font-face{ font-family:"微软雅黑"; } p.MsoNormal{ mso-style-name

APUE学习笔记:第九章 进程关系

9.1 引言 本章将更详尽地说明进程组以及POSIX.1引入的会话的概念.还将介绍登陆shell(登录时所调用的)和所有从登陆shell启动的进程之间的关系. 9.1 终端登陆 系统管理员创建通常名为/etc/ttys的文件,其中每个终端设备都有一行,每一行说明设备名传递给getty程序的参数.当系统自举时,内核创建进程ID为1的进程,依旧是init进程.init进程使系统进入多用户状态.init进程读文件/etc/ttys,对每一个允许登陆的终端设备,init调用一次fork,所生成的子进程则

c++ primer plus(第6版)中文版 第九章编程练习答案

首先,说明下环境: linux:fedora14: IDE:eclipse: python:python2.7 python框架:django web服务器:apache web服务器的python模块:mod_wsgi 写在前面: 之前用的windows下面的xampp,写的php后台,现在想转向linux下面的python,跟以前一样,选择apache和eclipse作为自己的开发工具. eclipse的python配置, 参见之前的博客:http://blog.csdn.net/zy416

深入浅出Zabbix 3.0 -- 第九章 数据可视化

第九章 数据可视化 Zabbix是一个非常灵活.强大的监控系统,它不仅能够监控大量不同类型的数据指标,并为这些数据及数据之间的关联提供了多种可视化工具,通过图形.展示屏.网络拓扑图等将数据直观的展现出来,实时的浏览和查看监控设备的状态. 9.1 图形 Zabbix 3.0中支持三种graphs(图形),即simple graphs(简单图形).ad-hocgraphs(自组图形)和customgraphs(自定义图形). 9.1.1 简单图形 简单图形是Zabbix系统内置的一种方法,为监控项数