鉴于本人英语能力有限,所以很多地方翻译只能翻译个大概,如果有错误欢迎大家指正~
我们都知道开发Android App的时候会把像字符串、图片、布局框架等资源携程xml放在res目录中然后在程序中去引用。
但是如果我们只提供一套资源文件,有时候碰到硬件配置不大相同的设备(比如屏幕的大小不同),显示就会出现差异,比如有些小图片在大屏幕设备上会变得很模糊。
为了让我们的图片等资源文件在各种Android设备中都能正常显示,我们就必须为不同配置的设备准备一套资源文件。
首先来看一下 资源文件目录 的大致结构:
MyProject/ src/ MyActivity.java res/ drawable/ icon.png layout/ main.xml info.xml values/ strings.xml
可以看到所有的资源文件都在 res/ 目录中,而不同类型的资源文件又放在不同名字的目录里,像icon.png这样的图片都放在res/dawable/ 中,像main.xml、info.xml这样的布局框架都放在res/layout/ 中,像strings.xml这样的字符串相关的东西可以放在 res/values/ 中。
也就是说,资源文件都是分类存放的,不同类型的资源文件会放在与之类型相关的目录中(从目录名就可以看出是否与其类型相关)。
下面给出官方Android开发者网站API文档中列出的 res/ 中可以存在的一些目录:
目录名 | 资源类型 |
---|---|
animator/ | 里面存放定义了 property animations 的xml文件。 |
anim/ | 里面存放定义了 tween animations.的xml文件。 (Property animations 也能存在这个目录里, 但是定义在 animator/ 目录中更容易区分这两种类型) |
color/ | 里面存放定义了Color State List(颜色状态表) 的xml文件。 |
drawable/ | 里面存放定义了如以下类型的位图 (
更详细的可以参考官方文件: Drawable Resources. |
layout/ | 里面存放定义的UI布局(layout)的xml文件. 不明白什么是layout,可以参考 Layout Resource. |
menu/ | 里面存放定义了菜单的xml文件,例如Options Menu, Context Menu, or Sub Menu(我的博客里也有关于这三个控件的使用介绍). 想了解menu控件可以参考 Menu Resource. |
raw/ (没用过,暂时先不翻译这个) | Arbitrary files to save in their raw form. To open these resources with a raw However, if you need access to original file names and file hierarchy, you might consider saving some resources in the |
values/ | 里面存放一些常量值,例如一些字符串、颜色的值、整数值等。 在的 res/ 的其他目录中,一个xml文件定义了一个资源,但是在 <resources> 可以看到每个<string>标签都定义了一个字符串资源。 在这个目录中每个xml文件分别代表了一种资源的类型,例如字符串资源都要定义在strings.xml文件中,而颜色值都要定义在color.xml中,下面列出了 values/ 中可以存在的一些xml文件名:
更多详情请参考 String Resources, Style Resource 和 More Resource Types。 |
xml/ | 里面存放能够在程序运行时通过调用Resources.getXML()来读取的xml文件。各种xml配置文件必须存放在这里,,比如searchable configuration. |
※注意:绝对不能在 res/ 目录中直接存放资源文件,否则会造成编译错误!!!!!
好了,那么关于资源文件组织的结构到这里就差不多搞清了,那么接下来就讲讲如何为不同配置的设备提供可选的资源。
刚才我们提到了不同类型的资源会被存储在有相应目录名的目录中,那么如果要为某些指定的设别提供相应的资源,只需按如下两点来设置:
(1) 在 res/ 中创建新的目录,目录的名字要按照 "<资源类型>+<限定符>" 的格式来命名。例如:drawable-hdpi 是针对高像素密度的设备,drawable-ldpi 是针对低像素密度的设备。
<资源类型>是上面那张表格中的任意值,用来指定资源类型。
<限定符>是下面这张表格的任意值,用来指定我们要针对设备的一些配置参数。限定符可以设定多个,用减号(-)来隔开,但是必须按照下面的表格中出现的顺序来排序!!!
(2) 不加限定符命名的目录会被系统认为是资源加载的默认目录,我们需要在我们的新目录中存放另一份适合其配置的资源文件,而且这个资源文件的名字要和在默认目录中的对应的资源文件的名字一样!!!!
下面给出官方Android开发者网站API文档中列出的可以使用的限定符:
要限定的内容 | 可用的限定符 | 描述 |
---|---|---|
移动电话国家代码和移动电话网络代码(MCC、MNC) | 例如:mcc310
mcc310-mnc004
mcc208-mnc00 等. | 表示从设备的SIM卡中读取的移动电话国家代码(MCC)或移动电话网络代码(MNC)。举个例子: 如果设备使用无线信号连接 (GSM 手机), 那么MCC和MNC代码是来自手机中的SIM卡。 你也可以只单独使用MCC (例如:你要在你的应用中加入针对特定国家的资源文件)。不要用这个限定符来指定语言,如果要针对某些语言,请使用"Language and region"限定符。 |
语言和地区(Language and region) | 例如:en fr en-rUS fr-rFR fr-rCA 等. | 设定语言的限定符由两个字母构成,在 ISO 639-1 中可以查看所有可选的值,可以参见左边小格中给出的如 en、fr 等例子。语言限定符后面可以附带(可选) ISO 3166-1-alpha-2 中定义的地区代码 (用小写的 " 这个限定符的值大小写不敏感。 如果用户改变了设备中语言的设定,你的App也会自动使用相应的语言。 |
布局方向(Layout Direction) | ldrtl ldltr | 应用中 layout 的布局方向。 这个设定适用于任何像layouts、drawables、values之类资源。 举个例子:如果你想为阿拉伯语提供指定的 layout 并且为其他"从右到左"的语言(如波斯语和希伯来语)提供一些一般的 layout ,那么可以这样做: res/ layout/ main.xml (默认的layout) layout-ar/ main.xml (为阿拉伯语定制的layout) layout-ldrtl/ main.xml (为除了阿拉伯语外的"从右到左"的语言定制的 layout, 因为"ar"限定符的优先级更高) 记住: 如果要使用"从右到左"的布局特性,你必须设置 |
最小宽度(smallestWidth) | sw<N>dp 例如: sw320dp sw600dp sw720dp 等. | 屏幕的最小尺寸。 其实最小宽度(smallestWidth)指的是屏幕的最小宽度和高度(你可能理解为了只是最小的宽度)。 你可以通过设定这个限定符来确保不论是横屏还是竖屏,App内的UI总是有至少 举个例子,如果你的layout要求屏幕的最小尺寸至少是600dp,那你可以这样来设置最小宽度(smallestWidth): 最小宽度(smallestWidth)值考虑到屏幕的布局和用户界面。 例如:如果有一些固定的UI元素占用了最小宽度中轴线的空间, 系统会把最小宽度声明的比真实的最小宽度更小,因为那些被使用了的像素你的UI已经不能使用了。 所以, 你所使用的值应该是你的layout所需要的最小尺寸(通常,这个值是你的layout所支持的最小尺寸,不论是横屏还是竖屏)。ps:这一段翻译的可能不大准确,我把官方原文的链接粘在这里这是链接。。,英语好的朋友可以直接看官方的文档。 下面列出了一些比较普遍的屏幕分辨率值,可以帮助你估量屏幕大小:
当你针对不同的最小宽度(smallestWidth)提供了不同的资源目录时,系统会自动使用最小宽度最接近(不超过)设备实际最小宽度的那一个目录。 这个限定符从 API level 13 开始才可使用. 可以看看 |
可获取的宽度(Available width) | w<N>dp 例如: w720dp w1024dp 等. | 指定可获得的最小屏幕宽度,以 当你为App提供了多个资源目录,而且他们都设定了不同的可获取宽度限定符时,系统会自动选择可获取宽度最接近(不超过)当前屏幕宽度的那个。这个值会考虑到屏幕的方向,所以如果有一些固定的UI元素在屏幕的左边或右边,那么将会使用比真实屏幕大小更小的值,要注意这些UI元素并减小屏幕的可获取空间。 这个限定符从 API level 13 开始才可使用. 可以参考一下 |
可获取高度(Available height) | h<N>dp 例如: h720dp h1024dp 等. | 指定可获得的最小屏幕高度,以 当你为App提供了多个资源目录,而且他们都设定了不同的可获取高度限定符时,系统会自动选择可获取高度最接近(不超过)当前屏幕高度的那个。这个值会考虑到屏幕的方向,所以如果有一些固定的UI元素在屏幕的顶部或底部,那么将会使用比真实屏幕大小更小的值,要注意这些UI元素并减小屏幕的可获取空间。 这个限定符从 API level 13 开始才可使用. 可以看看 |
屏幕大小(Screen size) | small normal large xlarge |
记住: 使用了大小限定符并不意味着资源只能被这个规格的屏幕使用。如果你没有为当前的屏幕配置提供更匹配的大小限定符,系统会自行使用现有资源中最匹配的那个资源。 注意: 如果你为资源目录添加了一个大于当前屏幕规格的屏幕大小限定符,系统将不会使用这些资源而且程序会在运行时崩溃! 这个限定符从 API level 4 开始才可使用. 可以看看 |
屏幕样貌(Screen aspect) | long notlong |
这个限定符从 API level 4 开始才可使用. 屏幕的长短是基于屏幕的长宽比决定的(一个"长"屏幕也很宽,一个"宽"的屏幕也很长),与屏幕的方向无关。 可以看看 |
屏幕方向(Screen orientation) | port land |
这个配置会受到屏幕的旋转的影响。 可以看看 |
UI 模式(UI mode) | car desk television |
Added in API level 8, television added in API 13. For information about how your app can respond when the device is inserted into or removed from a dock, read Determining and Monitoring the Docking State and Type. This can change during the life of your application if the user places the device in a dock. You can enable or disable some of these modes using |
夜间模式(Night mode) | night notnight |
这个限定符从 API level 8 开始才可使用. 这个设定会随着一天中时间的变化而改变。你可以通过 |
屏幕像素密度 (dpi) | ldpi mdpi hdpi xhdpi nodpi tvdpi |
ldpi、mdpi、hdpi、xhdpi是按照 3:4:6:8 的比例进行缩放的。 例如:一个ldpi 的 9x9 的位图在 mdpi 下会缩放为 12x12 的位图。一个hdpi的 18x18 的位图在 xhdpi 下会被缩放成 24x24 的位图。 如果你觉得你的图片在电视上或某些设备上显示的不够好,或者只是想要尝试一下 tvdpi 像素密度,那么可以告诉你这个缩放系数是 1.33*mdpi。例如:一个mdpi的 100px x 100px 的图片在tvdpi下会变成 133px x 133px。 记住: 使用了像素密度限定符并不意味着资源只能被这个像素密度的屏幕使用。如果你没有为当前的屏幕配置提供更匹配的像素密度限定符,系统会自行使用现有资源中最匹配的那个资源。 |
触摸屏类型(Touchscreen type) | notouch finger |
可以看看 |
键盘可用性(Keyboard availability) | keysexposed keyshidden keyssoft |
如果你提供了 这个设定会随着用户连接或拔下外接键盘而改变。 可以看看 |
第一文本输入方式(Primary text input method) | nokeys qwerty 12key |
可以看看 |
导航键是否可用(Navigation key availability) | navexposed navhidden |
这个设定会在用户调整导航键的可用性时也发生改变。 可以看看 |
第一非触屏导航方法(Primary non-touch navigation method) | nonav dpad trackball wheel |
可以看看 |
API 版本(API level) | 例如:v3 v4 v7 等. | 设备支持的API 版本。例如: |
※注意:并不是所有版本的Android都支持所有的限定符,最好总是为默认目录准备一套资源库!!!!
关于限定符的使用,要遵循以下规则:
(1) 可以通过减号(-)来同时使用多个限定符
(2) 如果同时使用多个限定符,必须按照上面这张表中各限定符出现的顺序来排列他们。
例如:正确的排列-> drawable-hdpi-port/
错误的排列-> drawable-port-hdpi/
(3) 资源目录不能嵌套,例如这样创建目录就是错误的:res/drawable/drawable-en/
。
(4) 限定符的值大小写不敏感。
(5) 每个目录同时只能支持一种类型的一个值。例如:你不能给单独一个资源目录同时添加法语和西班牙语的限定符,因为这两种限定符都是语言类的限定符。
只要你使用了相应的限定符来指定所针对的设备配置,那么系统会在加载资源时自动选择最适合当前设备的资源文件。
如何为设备提供兼容性更佳的资源:
为了能让我们的App支持更多的设备,我们最好总是为我们的App提供默认的资源目录!
举个例子吧:如果你的资源全部都设定了某种语言限定符,而且没有默认目录,那么如果设备上设置的语言中并没有对你所限定的语言的支持,那么你的App在运行时就会崩溃。但是如果你提供了一个默认目录,那么App可以正常运行,但是可能你的用户看不懂上面的文字,不过这总比直接崩溃要强。
如果转载请注明出处:http://blog.csdn.net/gophers/article/details/21281135