本文接引上文,主要解释如何在你的工程里组织资源和向不同的设备环境提供特有的资源。
一、分组资源种类
我们把所有资源分门别类的放在/res下的不同文件夹下,而且/res下的每一个文件夹的名称非常重要,代表不同的含义,如下表所示:
Table 1. Resource directories supported inside project
res/
directory.
Directory | Resource Type |
---|---|
animator/ | XML files that define propertyanimations. |
anim/ | XML files that define tweenanimations. (Property animations can also be saved in this directory, buttheanimator/ directory is preferred for property animations to distinguish between the twotypes.) |
color/ | XML files that define a state list of colors. See ColorState List Resource |
drawable/ | Bitmap files (
See Drawable Resources. |
layout/ | XML files that define a user interface layout. See Layout Resource. |
menu/ | XML files that define application menus, such as an Options Menu, Context Menu, or SubMenu. SeeMenu 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 considersaving some resources in the |
values/ | XML files that contain simple values, such as strings, integers, and colors. Whereas XML resource files in other Because each resource is defined with its own XML element, you can name the filewhatever you want and place different resource types in one file. However, for clarity, you mightwant to place unique resource types in different files. For example, here are some filenameconventions for resources you can create in this directory:
See String Resources, Style Resource, and More Resource Types. |
xml/ | Arbitrary XML files that can be read at runtime by calling Resources.getXML() . Various XML configuration filesmust be saved here, such as asearchable configuration. |
注意:不要直接将资源文件保存在/res目录下,这会造成构建错误。
你保存在表一上的子目录下的资源被认定为默认资源,也就是说这些资源被认定为你手机应用的默认设计和默认内容。那么如何为不同的设备或者不同的语言环境提供特定的资源?
二、提供特定的资源
提供特定资源使其在运行过程中,为你的应用探测当前的环境,提供对应的资源。
我们通过以下来分辨和划分特定的资源:
1、以<resources_name>-<config_qualifier>的命名形式在res文件夹下创建一个新的目录。
resources_name:对应相应的默认资源的目录名
config_qualifier:对应特殊资源的限定词,限定词必须是规定在表2的范围内。
你可以为一个目录添加一个以上的限定词,同过"-"隔开。
注意:当一个文件夹规定多个限定词时,他们必须按照表二的顺序排列,否则工程会忽略这个资源目录。
2、向相应的特殊子目录分配相应的资源,分配的资源名要和默认文件夹下的对应资源名一致。
比如:
“hdpi
”表明在这个文件夹里的资源适合高密度的屏幕。在不同文件夹里的资源适合不同的屏幕密度,但它们的文件名相同。通过这种方式,你在代码中使用的Resourse ID相同,但安卓机会通过比较当前手机配置和限定词,来选择最适合手机配置的资源。
以下是各种限定词的使用规则和排列顺序:
Table 2. Configuration qualifiernames.
Configuration | Qualifier Values | Description |
---|---|---|
MCC and MNC | Examples:mcc310
mcc310-mnc004
mcc208-mnc00 etc. | The mobile country code (MCC), optionally followed by mobile network code (MNC) from the SIM card in the device. For example, If the device uses a radio connection (GSM phone), the MCC and MNC values come from the SIM card. You can also use the MCC alone (for example, to include country-specific legalresources in your application). If you need to specify based on the language only, then use thelanguage and region qualifier instead (discussed next). If you decide to use the MCC andMNC qualifier, you should do so with care and test that it works as expected. Also see the configuration fields |
Language and region | Examples:en fr en-rUS fr-rFR fr-rCA etc. | The language is defined by a two-letter ISO 639-1 language code, optionally followed by a two letter ISO 3166-1-alpha-2 region code (preceded by lowercase " The codes are not case-sensitive; the This can change during the lifeof your application if the user changes his or her language in the system settings. SeeHandling Runtime Changes for information abouthow this can affect your application during runtime. See Localization for a complete guide to localizingyour application for other languages. Also see the |
Layout Direction | ldrtl ldltr | The layout direction of your application. This can apply to any resource such as layouts, drawables, or values. For example, if you want to provide some specific layout for the Arabic language and some generic layout for any other "right-to-left" language (like Persian or Hebrew) then you would have: res/ layout/ main.xml (Default layout) layout-ar/ main.xml (Specific layout for Arabic) layout-ldrtl/ main.xml (Any "right-to-left" language, except for Arabic, because the "ar" language qualifier has a higher precedence.) Note: To enable right-to-left layout features for your app, you must set Added in API level 17. |
smallestWidth | sw<N>dp Examples: sw320dp sw600dp sw720dp etc. | The fundamental size of a screen, as indicated by the shortest dimension of the availablescreen area. Specifically, the device's smallestWidth is the shortest of the screen's availableheight and width (you may also think of it as the "smallest possible width" for the screen). You canuse this qualifier to ensure that, regardless of the screen's current orientation, yourapplication has at least For example, if your layout requires that its smallest dimension of screen area be atleast 600 dp at all times, then you can use this qualifer to create the layout resources, The smallestWidth of a device takes into account screen decorations and system UI. Forexample, if the device has some persistent UI elements on the screen that account for space alongthe axis of the smallestWidth, the system declares the smallestWidth to be smaller than the actualscreen size, because those are screen pixels not available for your UI. Thus, the value you useshould be the actual smallest dimensionrequired by your layout (usually, this value is the"smallest width" that your layout supports, regardless of the screen's current orientation). Some values you might use here for common screen sizes:
When your application provides multiple resource directories with different values for the smallestWidth qualifier, the system uses the one closest to (without exceeding) thedevice's smallestWidth. Added in API level 13. Also see the For more information about designing for different screens and using thisqualifier, see theSupportingMultiple Screens developer guide. |
Available width | w<N>dp Examples: w720dp w1024dp etc. | Specifies a minimum available screen width, in When your application provides multiple resource directories with different values for this configuration, the system uses the one closest to (without exceeding) the device's current screen width. The value here takes into account screen decorations, so if the device has some persistent UI elements on the left or right edge of the display, it uses a value for the width that is smaller than the real screen size, accounting for these UI elements and reducing the application's available space. Added in API level 13. Also see the For more information about designing for different screens and using thisqualifier, see theSupportingMultiple Screens developer guide. |
Available height | h<N>dp Examples: h720dp h1024dp etc. | Specifies a minimum available screen height, in "dp" units at which the resource should be used—defined by the When your application provides multiple resource directories with different values for this configuration, the system uses the one closest to (without exceeding) the device's current screen height. The value here takes into account screen decorations, so if the device has some persistent UI elements on the top or bottom edge of the display, it uses a value for the height that is smaller than the real screen size, accounting for these UI elements and reducing the application's available space. Screen decorations that are not fixed (such as a phone status bar that can be hidden when full screen) arenot accounted for here, nor are window decorations like the title bar or action bar, so applications must be prepared to deal with a somewhat smaller space than they specify. Added in API level 13. Also see the For more information about designing for different screens and using thisqualifier, see theSupportingMultiple Screens developer guide. |
Screen size | small normal large xlarge |
Note: Using a size qualifier does not imply that theresources areonly for screens of that size. If you do not provide alternativeresources with qualifiers that better match the current device configuration, the system may usewhichever resources are thebest match. Caution: If all your resources use a size qualifier thatislarger than the current screen, the system willnot use them and yourapplication will crash at runtime (for example, if all layout resources are tagged with the Added in API level 4. See Supporting MultipleScreens for more information. Also see the |
Screen aspect | long notlong |
Added in API level 4. This is based purely on the aspect ratio of the screen (a "long" screen is wider). Thisis not related to the screen orientation. Also see the |
Screen orientation | port land |
This can change during the life of your application if the user rotates thescreen. SeeHandling Runtime Changes for information abouthow this affects your application during runtime. Also see the |
UI mode | car desk television |
Added in API level 8, television added in API 13, watch added in API 20. For information about how your app can respond when the device is inserted into or removed from a dock, readDeterminingand Monitoring the Docking State and Type. This can change during the life of your application if the user places the device in adock. You can enable or disable some of these modes using |
Night mode | night notnight |
Added in API level 8. This can change during the life of your application if night mode is left inauto mode (default), in which case the mode changes based on the time of day. You can enableor disable this mode using |
Screen pixel density (dpi) | ldpi mdpi hdpi xhdpi xxhdpi xxxhdpi nodpi tvdpi |
There is a 3:4:6:8:12:16 scaling ratio between the six primary densities (ignoring thetvdpi density). So, a 9x9 bitmap in ldpi is 12x12 in mdpi, 18x18 in hdpi, 24x24 in xhdpi and so on. If you decide that your image resources don't look good enough on a television orother certain devices and want to try tvdpi resources, the scaling factor is 1.33*mdpi. Forexample, a 100px x 100px image for mdpi screens should be 133px x 133px for tvdpi. Note: Using a density qualifier does not imply that theresources areonly for screens of that density. If you do not provide alternativeresources with qualifiers that better match the current device configuration, the system may usewhichever resources are thebest match. See Supporting MultipleScreens for more information about how to handle different screen densities and how Androidmight scale your bitmaps to fit the current density. |
Touchscreen type | notouch finger |
Also see the |
Keyboard availability | keysexposed keyshidden keyssoft |
If you provide This can change during the life of your application if the user opens a hardwarekeyboard. SeeHandling Runtime Changes for information about howthis affects your application during runtime. Also see the configuration fields |
Primary text input method | nokeys qwerty 12key |
Also see the |
Navigation key availability | navexposed navhidden |
This can change during the life of your application if the user reveals the navigationkeys. SeeHandling Runtime Changes forinformation about how this affects your application during runtime. Also see the |
Primary non-touch navigation method | nonav dpad trackball wheel |
Also see the |
Platform Version (API level) | Examples:v3 v4 v7 etc. | The API level supported by the device. For example, |
限定词使用规则
以下是使用限定词的几个规则:
1、你可以用多个限定词来区分一种特殊的资源,限定词之间用“-”隔开。
2、限定词必须按表二的顺序排列。例如:
正确:drawable-port-hdpi/
错误:drawable-hdpi-port/
3、特定的资源目录不能被嵌套。例如:
不存在res/drawable/drawable-en/
4、值是区分大小写的。但是为了避免在大小写系统上出现错误,系统在处理数据前会先把所有大写转化成小写字母,所以任何名字中的大写字母只是为了提高可读性。
5、同类型的限定词同时只能有一个在资源名上出现。比如你想要为西班牙和法国的手机app用同一个图片,你不可以用drawable-rES-rFR/
。你只能用两个内容相同的目录drawable-rES/
和drawable-rFR/。但你确实不需要在相同的位置复制同一个文件,只需要创建一个别名资源。具体可见下部分创建别名资源。
在通过限定词创建了
特定资源的目录后,Android会自动根据当前环境,提供最合适的资源。每次资源被请求使用,Android会自动检查,寻找最合适的资源,如果不存在最合适的资源,系统会使用默认资源。
创建别名资源
当你希望一个特定资源用在不同的特定环境时(指的不是默认资源),你不需要在两个不同的特定资源目录下存放相同的资源,你只需要将特定资源放在默认文件夹里,然后在么个特定资源目录里,加入指向该资源的XML文件。
例如:
将icon_ca.png
特殊资源使用在英语和法语环境下,我们把icon_ca.png
放在res/drawable/
目录下,再在res/drawable-en-rCA/
和res/drawable-fr-rCA/
下放置icon.xml
,
icon.xml
只允许我们创建一种版本的PNG文件。icon.xml
具体形式见下文。
注意:不是所有的资源都可以使用别名资源,通常animation, menu, raw,和其他在/xml文件夹里的资源没有这个现象。
Drawable
<?xml version="1.0" encoding="utf-8"?>
<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
android:src="@drawable/icon_ca" />
如果你在res/drawable-en-rCA/
中保存的是icon.xml
,R文件内显示的是R.drawable.icon
,实际上它就是存放在默认目录下的R.drawable.icon_ca
资源的映像。
Layout
<?xml version="1.0" encoding="utf-8"?>
<merge>
<include layout="@layout/main_ltr"/>
</merge>
具体同上,注意标签名的不同。Strings and other simple values
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="hello">Hello</string>
<string name="hi">@string/hello</string>
</resources>
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="yellow">#f00</color>
<color name="highlight">@color/red</color>
</resources
现在,R.string.hi
资源就是R.string.hello资源的映射。
三、提供最好的资源兼容性。
为了保证你的app能够在多个设备上运行,必须在默认资源环境中设置资源。否则如果你只在各种含有限定词的目录下放置资源,一旦运行在一个app不支持的语言环境下,就会崩溃。
放置默认资源的原因如此重要并不只是因为你的应用会遇到你没有想到的环境,事实上更多是因为有时新版本增加的限定词,旧版本无法支持。即当你在未设置默认资源时使用一个新的限定词,而设备却保持原有的编码兼容性,于是设备无法识别你增加的限定词,在运行时就会出现崩溃。比如我们设置一个工程的最低SDK为4,那么在我们使用夜间模式下的图片时,系统就会因为无法找到drawable-night/
内的图片而崩溃(夜间模式的限定词在SDK8才开始使用)。此时我们最好就是在默认资源和drawable-night/
都设置相应的图片。
所以一般我们先将所有可能用到的图片设置在默认资源里,再相应的添加特定资源。
这个规则的唯一例外是在SDK4版本以上的版本,不需要为屏幕密度相关的限定词在默认目录里添加默认资源,因为即使没有默认资源,Android系统也会寻找分辨率最合适的图片。也因此最好的效果就是在图片的三个文件夹里,都放置相应的资源。这也就解释了我们创建SDK4版本的Android工程时drawable
相关的资源文件如此个别,没有默认目录。
四、Android工程师如何发现最匹配的资源。
Android系统依据当前运行的环境选择特定的资源。为了显示android是如何工作的,假设以下资源目录分别存放着不用版本的图片:
drawable/ drawable-en/ drawable-fr-rCA/ drawable-en-port/ drawable-en-notouch-12key/ drawable-port-ldpi/ drawable-port-notouch-12key/而且假设具有如下环境:
场所 Locale = en-GB
屏幕方向 Screen orientation = port
屏幕分辨率 Screen pixel density = hdpi
触摸屏模式 Touchscreen type = notouch
首选文本输入方法 Primary text input method = 12key
最终Android系统选择了
drawable-en-port
文件夹内的图片。
选择流程如下:
1、排除与当前环境冲突的资源
drawable/ drawable-en/例外:drawable类型的资源不会因为冲突而被排除,详见 Supporting MultipleScreensdrawable-fr-rCA/drawable-en-port/ drawable-en-notouch-12key/ drawable-port-ldpi/ drawable-port-notouch-12key/
2、根据表2,从上自下挑选出最高优先级的限制词。
3、再看我们备选的资源目录里是否含有这个限制词,如果含有进入第4步,如果没有回到第2步,选择下一个限制词。
4、排除不含有我们挑选出的限定词的资源目录。
例外:依旧是drawable,系统会挑选出最接近的屏幕密度的图片,不管是否存在这个屏幕密度的限定词 。而且通常系统会选择更大的图片。drawable/drawable-en/ drawable-en-port/ drawable-en-notouch-12key/drawable-port-ldpi/ drawable-port-notouch-12key/
5、重复上述步骤,直到只剩下一个限定词。
drawable-en/drawable-en-port/drawable-en-notouch-12key/
尽管这种工作模式可以响应所有资源的请求,但系统还是会考虑其他方面的影响。最优化的方案是一旦设备环境确定,就会永远的排除一些冲突的资源目录,即建立一个可用的资源目录池。
当依据屏幕大小的限定词时,如果没有最合适的资源,系统会选择偏小的资源,以避免选择偏大的资源,而是程序崩溃。
注意:限定词在表2的顺序即限定词优先级比资源目录含有的限定词的多少更加重要。