由于设备的多样性,Android 系统会检测当前设备配置,并为应用加载合适(最匹配)的资源。下面根据经验结合官方api,详细说下系统适配的规则。

一、10种资源。在 res中以 <resources_name>-<config_qualifier> 形式命名目录。Android系统一共为应用提供了10类资源目录(即resources_name),如下表:

目录

资源类型

animator/

用于定义属性动画的 XML 文件

anim/

定义渐变动画的 XML 文件

color/

用于定义颜色状态列表

drawable/

位图文件(.png、.9.png、.jpg、.gif)、状态列表、形状...

mipmap/

适用于不同启动器图标密度的 mipmap/ 文件夹管理启动器图标的详细信息。

layout/

用于定义用户界面布局。

menu/

用于定义应用菜单(如选项菜单、上下文菜单或子菜单)的 。

raw/

要以原始形式保存的任意文件(2.3版本要求1M)。

values/

包含字符串、整型数和颜色等简单值的 

xml/

可以在运行时通过调用 Resources.getXML() 读取的任意 XML 文件

在IDE中如下图:

 

Android的res文件 android res目录_res

开发者需要根据不同的资源文件,放入对应的文件夹或者目录下,这里提下几个目录:

1.animator和anim一般都用来放动画,官方文档中说animator放属性动画,但其实动画统一放在anim也是没问题的,如果app动画不多,统一放在一个目录还便于管理。

2.Color通常防止颜色集合,这个跟value下面的颜色值要区分开来,value里面的color文件存放的是具体的颜色值,例如:

 

Android的res文件 android res目录_android_02

而color/防止的是颜色的状态列表,set集合

3.Raw里面,放置不需要编译成二进制的文件,与assets目录的区别就是,单个文件大小有约1m的限制,assets单个文件允许的大小要比raw大。另外,raw里面可以通过resource获取,assets里面的文件,只能通过assetmanager读取。

二、18种资源限定符。系统给app提供了上述10种resources_name后,还给大多数的资源,提供了18种限定符(config_qualifier)的支持,如下表:

优先级

配置

限定符值

1

MCC 

移动国家代码,示例:mcc310、mcc310-mnc004、mcc208-mnc00等等

2

语言和区域

语言代码定义,示例:en、fr、en-rUS、fr-rFR、fr-rCA等等

3

布局方向(api-17)

应用的布局方向,ldrtl 是指“布局方向从右到左”。ldltr 是指“布局方向从左到右”,这是默认的隐式值。

4

smallestWidth(api-13)

屏幕的基本尺寸,由可用屏幕区域的最小尺寸指定。sw<N>dp示例:sw320dp、sw600dp、sw720dp等等

5

可用宽度

指定资源应该使用的最小可用屏幕宽度。w<N>dp示例:w720dp、w1024dp等等

6

可用高度

指定资源应该使用的最小可用屏幕高度。h<N>dp示例:h720dp、h1024dp等等

7

屏幕尺寸

small(320x426 dp)、normal(320x470 dp)、large(480x640 dp)、xlarge(720x960 dp)

8

屏幕纵横比

long(宽屏)、notlong(非宽屏)

9

屏幕方向

port、land

10

UI 模式

car(车载手机座)、desk、television、appliancewatch

11

夜间模式

Night、notnight

12

屏幕像素密度 (dpi)

ldpi、mdpi、hdpi、xhdpi、xxhdpi、xxxhdpi、nodpi、tvdpi

13

触摸屏类型

notouch:设备没有触摸屏、finger

14

键盘可用性

keysexposed:设备具有可用的键盘、keyshidden、keyssoft

15

主要文本输入法

nokeys:设备没有用于文本输入的硬按键、qwerty、12key

16

导航键可用性

Navexposed、navhidden

17

主要非触摸导航方法

Nonav、dpad、trackball、wheel

18

平台版本(API 级别)

示例:v3、v4、v7 等等

需要注意的是,相当一部分的资源限定符是在不同的系统api上逐步增加的,不要以为所有的系统版本都支持18中限定符,因此当你确定要添加该限定符时,应该要确保当前的api版本是否支持。

三、适配的原则:

当您请求要为其提供备用资源的资源时,Android 会根据当前的设备配置选择要在运行时使用的备用资源。规则如下:

1.淘汰与设备配置冲突的资源文件。

2.选择上述限定符表中优先级最高的限定符。(先从 MCC 开始,然后下移。)

3.是否有资源目录包括此限定符?

4.淘汰不含此限定符的资源目录。

5.返回并重复第 2 步、第 3 步和第 4 步,直到只剩下一个目录为止。

过程如下图:

Android的res文件 android res目录_Android的res文件_03

四、一个sample:

上面说了规则,下面举个例子,假设设备配置如下:

区域设置 = en-GB 

屏幕方向 = port 

屏幕像素密度 = hdpi 

触摸屏类型 = notouch 

主要文本输入法 = 12key

 

有下面的资源去适配:

drawable/

drawable-en/

drawable-fr-rCA/

drawable-en-port/

drawable-en-notouch-12key/

drawable-land-hdpi/

drawable-port-notouch-12key/

 

1.根据四中的原则,第一步,淘汰与设备配置冲突的资源文件,因此下面的资源被淘汰:

drawable-fr-rCA/

drawable-land-hdpi/

2.第二、三步,选择限定符表中优先级最高的限定符,从mcc往下看,第一个mcc没有,第二个en,资源里面有目录包含有。

3.第四步,淘汰不含此限定符(en)的资源目录:

drawable/

drawable-port-notouch-12key/

4.第五步,重复上面的流程,port比notouch优先级高,所以淘汰

drawable/

drawable-en-notouch-12key/

5.最后,剩下

drawable-en-port/

 

这个就是系统的适配原则。

五、再说下drawable图片的适配,android系统是如何适配不同密度的手机呢,如下图:

 

Android的res文件 android res目录_资源适配_04

如果要适配6中密度的手机,难道要放6套图片到各自的限定符目录中吗,这显然是不可能的,大小无法接受,通常情况是针对高屏幕密度(240dpi,一般对应分辨率为480x800)的手机,设计一套满足视觉效果的图片基本就能满足要求。

那么对于不落在这个密度范围内的手机,系统是如何适配的呢?

原则也很简单,系统会优先查找比当前密度更大的目录,看是否存在对应的图片,如手机为hdpi,若app里面hdpi目录下,没有图片,系统会依次查找xhdpi、xxhdpi、xxxhdpi的文件,如果仍然没有,再查找比他低密度的目录。

这样查找的好处在于,系统将使用比当前密度更大的图片来显示,防止图片拉伸变成锯齿。