你总应该将诸如图片,字符之类的资源从应用代码中提取出来,这样就可以单独的维护他们。你还应该通过将它们按特定的资源目录名称分组的方式,为特定的设备配置提供可替换资源。安卓系统在运行时根据当前配置实用合适的资源。例如,你可能会想根据不同屏幕尺寸提供不同的界面布局,根据语言设置提供不同的字符串。

一旦提取了应用资源, 你就可以使用项目中R类生成的资源ID来使用它们。访问资源文档讨论了如何使用应用资源。本文档展示了如何为安卓项目资源分组和为特定设备配置提供可替换资源。

为资源类型分组

你应该将每种类型资源放到项目res/目录的特定子目录中。例如,下面是一个示例项目的文件结构:

正如你在这个例子中所见,res/目录包含了所有的资源(在子目录中):一个图片资源,两个布局资源,和一个字符串资源文件。资源目录的命名是非常重要的,如表1中所述。

表1.项目res/目录中支持的资源目录。

android的开发工具集合(开发中文引导-提供资源)(1)

警告:不能直接在res/目录保存资源——这将导致编译错误。

要了解某种资源类型的详细信息,请参考资源类型文档。

保存在表1中定义的子目录中的资源是你的“默认”资源。这就是说,这些资源定义了应用的默认设计和内容。但是,不同的安卓设备可能调用不同的资源类型。例如,如果一个设备有比普通设备更大的屏幕,那么你应该提供不同的布局资源来利用额外的屏幕空间。或者,如何一个设备有不同的语言设置,那么你应该提供不同的字符资源来翻译用户界面的文本。要为不同的设备配置提供不同的资源,除了默认资源,你还需要提供可替换资源。

提供可替换资源

android的开发工具集合(开发中文引导-提供资源)(2)

图1。两个不同的设备,每个都使用不同的布局资源。

几乎每种应用都应该提供可替换资源以支持特定的设备配置。例如,你应该为不同的屏幕尺寸提供可替换的可绘制资源,为不同的语言提供可替换的字符资源。安卓系统在运行时检测当前设备的配置并为应用读取适合的资源。

为一组资源指定特定配置的可替换资源:

1. 在res/创建一个新的目录,按照<resources_name>-<config_qualifier>的格式命名。

你可以附加多个<qualifier>(译者注:上面提到的修饰符)。每个单独的修饰符带有一个破折号。

警告:附加多个修饰符的时候,你必须按照表2所列相同的顺序排列他们。如果修饰符排序错误,这些资源将被忽略。

2. 在这个新目录中保存各自的可替换资源。这些资源文件必须按照默认资源文件完全相同的名称命名。

例如,下面是一些默认和可替换资源:

那个目录的hdpi修饰符用于高密度屏幕的设备。这些可绘制物体目录的每个图片都用于特定屏幕尺寸的大小调整,但是,文件名称必须完全相同。这样,用来引用icon.png和background.png图片的资源ID就总是一样的,不过安卓系统通过比较设备配置信息和资源目录名称的修饰符来挑选最适合当前设备的每个资源版本。

安卓系统支持多种配置修饰符,你可以通过用破折号分隔每个修饰符来为一个目录名称添加多个修饰符。表2列出了有效的配置修饰符,按照优先顺序——如果为资源目录使用多个修饰符,你必须以这张表中列出的顺序将他们添加到目录名称中。

表2。配置修饰符名称。

android的开发工具集合(开发中文引导-提供资源)(3)

android的开发工具集合(开发中文引导-提供资源)(4)

android的开发工具集合(开发中文引导-提供资源)(5)

注意:一些修饰符是自动安卓1.0添加的,所以并不是所有版本的安卓系统都支持所有修饰符。使用新的修饰符将隐含地添加了平台版本修饰符,以让旧的设备确保忽略它。例如,使用w600dp修饰符会自动包含v13修饰符,因为有效宽度修饰符是在API级别13版本新添加的修饰符。为了避免任何问题,总要包含一组默认资源(一组没有修饰符的资源)。要了解更多信息,请参考提供最佳的设备与资源的兼容性文档。

修饰符名称规则

下面是一些使用配置修饰符名称的规则:

当你将这些可替换资源保存到使用这些修饰符定义的目录中后,安卓系统会根据当前设备配置自动应用资源。每次需要资源的时候,安卓系统检测包含请求资源文件的可替换资源目录,然后找到最适合的资源(后面讨论)。如果没匹配特定设备的可替换资源,那么安卓系统会使用相应的默认资源(没有包含配置修饰符的特定资源类型的一组资源)。

创建别名资源

当你有想用于多个设备配置(但不想提供默认资源)的资源时,你不必将同样的资源放到多个可替换资源目录。相反,你可以(在某些情况下)创建作为保存在默认资源目录资源别名的可替换资源。

注意:不是所有资源都支持可以向其他资源创建别名的机制。特别是,动画,菜单,原始数据,和其他xml/中未指定的资源不提供此功能。

例如,假设你有一个应用图标,icon.png,且需要不同地区的独特版本。但是,两个地区,英国-加拿大和法国-加拿大,需要使用相同的版本。你可能会认为需要将同样的图片拷贝到英国-加拿大和英国-加拿大两者的资源目录中,但这并不需要。相反,你可以将用于两者的图片都保存为icon_ca.png(任何不是icon.png的名称)并将它放到默认的res/drawable/目录。然后在res/drawable-en-rCA/和res/drawable-fr-rCA/创建一个icon.xml文件使用<bitmap>元素引用icon_ca.png图片。这将允许仅保存PNG文件的一个版本和俩个指向它的XML小文件。(在下面显示了一个示例XML文件。)

可绘制物体

要创建一个已存在的可绘制物体的别名,使用<bitmap>元素。例如:

如果将这个文件保存为icon.xml(在一个可替换资源目录,如res/drawable-en-rCA/),它被编译成一个你可以用R.drawable.icon引用的资源,但实际上是R.drawable.icon_ca资源的别名(保存在res/drawable/目录)。

布局

要创建已存在布局的别名,使用<include>元素,包装在<merge>标签中。例如:

如果你将这个文件保存为main.xml,它会被编译成可以使用R.layout.main引用的资源,但实际上是R.layout.main_ltr资源的别名。

字符串和其他简单值

要创建一个已存在字符串的别名,简单的使用想要用作新字符串的值便可。例如:

R.string.hi资源现在成为了R.string.hello的别名。

Other simple valueswork the same way. For example, a color:

提供最佳的设备与资源的兼容性

为了让你的应用支持多个设备配置,总是为应用使用的每种资源类型提供默认资源是非常重要的。

例如,如果应用支持多种语言,总要包含一个没有语言和区域修饰符的values/目录(在这里保存了字符串)。相反如果你将所有的字符串都放到带有语言和区域修饰符的目录中,那么应用在设置了应用所不支持的语言的设备上将会崩溃。但是只要提供了默认的values/资源,那么应用会正确的运行(尽管用户不理解那种语言——这也比崩溃要好)。

同样的,如果你根据屏幕朝向提供了不同的布局资源,应该采用一个朝向为默认布局。例如,保留一个作为默认布局,如使用layout/用于水平布局,layout-port/用于竖直布局,而不是为layout-land/提供水平布局资源和为layout-port/提供竖直布局资源。

提供默认资源之所以重要不仅因为应用可能会运行在非预期的配置上,也应为新版本的安卓系统有时会添加旧版本不支持的配置修饰符,那么当就旧版本的安卓系统运行你的应用时,如果你没提供默认资源它会崩溃,因为它不能使用带有新修饰符命名的资源。例如,如果你的minSdkVersion设置为4,并将所有可绘制资源限定为使用夜间模式(night 或notnight,API级别8添加),那么API级别的设备将不能使用你的可绘制资源并会崩溃。这种情况,你也许想要notnight做为默认资源,因此你应该去掉那个修饰符,因此你的资源既可以处于drawable/也可以处于drawable-night/。

因此,为了提供最佳的设备兼容性,总要为保持应用可以正常运行提供默认资源。然后使用配置修饰符创建特定设备配置的可替换资源。

这个规则有一个例外:如果应用的minSdkVersion设置为4或更高,当提供了屏幕密度修饰符的可替换资源时,你确实不需要默认的可绘制资源。即便没有默认可绘制资源,安卓系统也可以在可替换的屏幕密度之间找到最合适的资源并在必要时缩放位图。但是,为了在所有设备上获得最佳体验,你应该为所有3种密度类型提供可替换的可绘制资源。

安卓系统如何找到最合适的资源

当你请求一个提供的可以换资源时,安卓系统在运行根据当前设备配置选择可以换资源来使用。为了展示安卓系统如何选择一个可替换资源,假设下面的每个可绘制物体目录都包含同样图片的不同版本:

然后假定下面是设备的配置:

通过比较设备配置与可用的可替换资源,安卓系统从drawable-en-port选择了可绘制物体。

系统确定使用那个资源的决定使用了如下逻辑:

android的开发工具集合(开发中文引导-提供资源)(6)

图2。安卓系统如何找到最合适的资源的流程图。

1. 剔除与设备配置相抵触的资源。

drawable-fr-rCA/ 目录被剔除,因为它区域修饰符与所需区域相抵触了。

警告:屏幕像素密度是一种不会由于配置原因被剔除的修饰符。即便设备的屏幕密度是hdpi,drawable-port-ldpi/也不会被剔除,因为此刻每个屏幕密度都被看作一个匹配。更多有用的信息可以参考支持多屏文档。

2. 选择列表中(表2)最高优先(接下来)的修饰符。(从MCC开始,然后向下移动)

3. 有任何资源目录包含这个修饰符吗?

4. 剔除不包含这个修饰符的资源目录。这个例子中,系统剔除了所有不包含语言修饰符的目录:

例外:如果问题是屏幕像素密度,系统会选择最接近设备屏幕密度的选项。通常,相较于放大一个较小的原始图片安卓系统更偏好选择一个较大的原始图片来缩小。参考支持多屏文档了解更多信息。

5. 返回重复步骤2,3,和4直到仅剩一个目录为止。这个例子中,屏幕朝向是下一个有任何适合的修饰符的选择。因此,没有指定屏幕朝向的资源被剔除:

保留的目录是 drawable-en-port.

尽管这个处理会为每个请求的资源执行,系统会近一步优化一些方面。一种优化是一旦知道了设备的配置,它会剔除永远不会匹配的可替换资源。例如,如果配置的语言是英语("en"),那么任何拥有设为其他不是英语的语言修饰符的资源将永远不会被包含到资源检测池中(尽管没有语言修饰符的资源目录仍然包含在内。译者注:指待检测的匹配资源目录列表)。

当根据屏幕大小修饰符选择资源时,如果没有更加合适的资源,系统会使用设计用于比当前屏幕更小屏幕尺寸的资源(例如,必要时大屏会使用普通屏幕的资源)。但是,如果仅有的可用资源的尺寸比当前屏幕大,那么系统不会使用它们,并且如果没有其他适合设备配置的资源你的应用会崩溃(例如,如果所有的资源都标有xlarge修饰符,但设备是普通大小的屏幕)。

注意:修饰符(表2中)的优先要比精确匹配设备的数量更重要。例如,在上面的第4步中,列表中的最后选择包含了3个精确匹配设备的选项(朝向,触屏类型,和输入方法),但drawable-en仅有一个匹配(语言)的参数。但是,语言比其他的修饰符有更高的优先,因此 drawable-port-notouch-12key出局了(:>)。

要了解更多关于如何在应用中使用资源的信息,继续阅读访问资源文档。

百度首发地址:《android中文开发向导》

,