Android Resource篇--- I 存放资源文件的规则

概述

Resource的含义: 一款优秀的APP不能只包含代码.Resource是指为代码提供服务的其它文件和静态内容, 比如图片, 布局文件, 用户接口字符串等.

使用Resource的好处: 可以将资源跟代码分离, 更便于独立管理. 并且可以大大提高不同配置下APP的适应性, 比如不同的屏幕尺寸, 不同的语言等.

Resource典型的应用场景: 每种Resource都支持默认和多个备选资源,默认资源用于一般情况(没有特殊的配置), 备选资源一般用于指定的配置. Resource通过/res下文件夹的名字来区分它们.栗子:

如果我们不使用指定的Resource, 只有一种默认Resource, 那么当APP运行在不同配置的设备上的时候, 就会不加区分的显示成同一个样子:

Android Resource篇--- I 存放资源文件的规则_第1张图片

这显然不怎么合理, 为了应对这样的场景, 我们为横向设备指定了特殊的Resource, 在/res/layout-land/目录下增加布局文件, 那么在不同设备上, 就会显示的合理得多:

Android Resource篇--- I 存放资源文件的规则_第2张图片


制作资源文件

Resource们都在哪:

在一个Android工程中, 所有的Resource文件都放在/res目录下, 一个典型的工程目录大概长这样:

Android Resource篇--- I 存放资源文件的规则_第3张图片

res支持的子目录包括:

animator: 用于定义动画属性的xml文件.

anim: 用于存放”tween动画”的xml文件.

color: 用于存放”状态颜色列表”的xml文件.

drawable: 用于存放bitmap文件(png,9.png, jpg, gif)或者定义drawable的xml文件.

mipmap: 用于存放APP图标的drawable文件.

layout: 存放界面布局文件.

menu: 存放菜单定义文件.

raw: 不希望在编译的时候被改变的文件.

values: 存放定义简单值的文件, 比如字符串, 整形, 颜色等.

xml: 存放任意XML文件, 可以通过Resource.getXML()方法获得. 各种XML配置文件, 需要存放在此处.

我们不能在res目录下直接存放xml文件, 这会导致编译错误.


管理res目录

如何通过管理res目录提供备选的资源文件呢? 假如我们已经有了一份默认的资源文件, 它们长这样: 


这时候我们还需要一份为高密度屏(可以理解为某一指定尺寸的屏)准备一份特殊的资源, 那么我们必须提供一份额外的资源文件:

Android Resource篇--- I 存放资源文件的规则_第4张图片

只需要在res下创建一个新的子文件夹即可, 资源文件的名字跟默认的资源文件名称一样, 但是文件夹的名字是需要注意的部分, 它需要根据配置需要指定文件夹名. 该名称的规则如是<资源类型名>-<修饰符>. Android会根据系统的配置来查找符合条件的文件夹, 然后到该文件夹中获取资源.

<资源类型名>:这个比较简单, 就是上面提到的drawable,layout等.

<修饰符>:这个稍微复杂, 需要遵守指定的顺序和规则,必须按照如下表格的顺序排列, 中间通过”-“连接, 并且不能冲突.

配置

修饰符

描述

MCC和MNC

例子:

mcc310,

mcc310-mnc004,

mcc208-mnc00

MCC是移动国家代码, MNC是移动网络代码. MCC可以单独使用, MNC只能跟在MCC后面.

语言和区域

例子:

en, fr, en-rUS

语言由两个字母的ISO 639-1语言码表示, 地区码由两个字母的ISO 3166-1-alpha-2区域码表示. 其中区域码可选, 并且用”r”前缀通过”-“与语言码连接. 用户在APP运行的时候修改了系统的语言配置会影响该资源的选择.

布局方向

ldrtl, ldltr

布局的方向, ldrtl意思是” layout-direction-right-to-left”, ldltr意思是” layout-direction-left-to-right”, ldltr是默认的. 在一些特殊的语言中会用到, 比如波斯语和希伯来语, 它们的书写方向是从右向左的.

最小宽度

格式:swdp

如: sw320dp,

sw720dp

无论屏幕是横屏还是竖屏, 这里的宽度指的都是屏幕的”较短边”, 通常跟layout配合使用. 比如res/layout-sw600dp/意思是此目录下的资源用于宽度至少为600dp的设备. 1dp=1/160英寸.

有效宽度

格式:wdp

如: w720dp,

w1024dp

指定最小有效屏幕宽度, 单位为dp, 这个值会随着屏幕方向的变化而改变.

有效高度

格式:hdp

如:h720dp,

h1024dp

指定最小有效屏幕高度, 单位为dp, 这个值会随着屏幕方向改变而改变.

屏幕尺寸

small, normal, large, xlarge

small: 小屏幕设备, 大概尺寸为320x426dp. 与QVGA的低密度屏或者VGA的高密度屏尺寸相近.

normal: 普通屏幕设备, 最小布局尺寸大概是320x470dp. 比如WQVGA低密度屏, HVGA中密度屏, WVGA的高密度屏.

large: 大屏幕设备, 最小布局尺寸大概是480x640dp. 比如VGA和WVGA的中密度屏.

xlarge: 巨大屏幕设备, 最小布局尺寸大约是720x960dp, 比如HVGA中密度屏. 这种尺寸通常用于平板.

注意: 使用某种屏幕尺寸修饰符并不意味着资源只能用于相应密度的设备, 如果系统不能找到完全匹配的资源, 那么它会自动匹配适合的资源.

如果所有的资源都比实际的屏幕要大, 那么系统将崩溃.

屏幕宽高比

long, notlong

long: 长屏, 比如WQVGA, WVGA, FWVGA

notlong: 短屏?, 比如QVGA, HVGA, VGA.

判断根据是屏幕宽高比, 与屏幕方向无关.

屏幕方向

port, land

port: 屏幕方向是纵向(垂直).

land:设备屏幕方向是横向(水平).

APP运行时可能改变的配置.

UI模式

car, desk, television, appliance, watch

car: 设备插在”car dock”上.

desk: 设备插在”desk dock”上.

television: Android电视设备.

appliance: 没有显示设备的Android

watch: 有显示屏的Android可穿戴设备.

夜间模式

night, notnight.

night:夜间模式

notnight: 白天模式

如果设置成Auto, 那么系统将会根据时间来判断应该使用哪些资源.

屏幕像素密度

Ldpi,

mdpi,

hdpi,

xhdpi,

xxhdpi,

xxxhdpi,

nodpi,

tvdpi

ldpi: 低密度屏, 约120dpi

mdpi: 中密度屏(HVGA), 大约160dpi

hdpi: 高密度屏, 大约240dpi

xhdpi: 大约320dpi

xxhdpi: 大约480dpi

xxxhdpi: 大约640dpi

nodpi: 可以用于存放不希望被缩放的位图资源

tvdpi: 位于mdpi和hdpi之间, 大约213dpi, 通常用于电视上.

触屏种类

notouch,

finger

notouch: 设备没有触摸屏.

finger: 设备有触摸屏.

键盘可用性

keysexposed,

keyshidden,

keyssoft

keysexposed: 有键盘状态, 包括软键盘弹出状态和硬键盘打开.

keyshidden: 设备有硬件键盘但是处于关闭状态

keyssoft: 设备软键盘功能打开了,不管它是不是可见.

主要文本输入方式

nokeys,

qwerty,

12key,

nokeys: 设备没有硬件键盘.

qwerty: 设备带有全键盘(qwerty).

12key: 设备带有12-key键盘,不管是不是可见.

导航键是否可用

navexposed

navhidden

navexposed:导航键可用.

navhidden: 导航键不可用.

这两种状态可能在程序运行时切换.

主要的非触摸导航方式

nonav,

dpad,

trackball,

wheel

nonav:无导航设备

dpad:带有硬件触摸板导航设备

traceball:带有轨迹球(traceball)的设备

wheel:带有方向轮的设备.

平台版本(API级别)

如v3, v4, v7等

设备支持的API级别

修饰符的命名规则:

可以为一个备选资源指定多个修饰符,比如drawable-en-rUS-land指定US-English横向屏幕.

顺序必须按照上面表格中的顺序, 比如drawable-hdpi-port是错误的, 必须写成drawable-port-hdpi.

备选资源不能嵌套. 比如res/drawable/drawable-en/, 这样的目录结构是错误的.

目录名是大小写不敏感的, 编译器会自动都转为小写.

每种修饰符类型只支持一个值, 比如不能出现drawable-rES-rFR/这样的目录. 如果需要同时支持ES和FR, 那么需要使用两个备选资源目录, 用drawable-rES和drawable-rFR代替.

 

Android会如何匹配这些资源:

举栗子: 当系统配置是这样

Locale = en-GB

Screen orientation = port

Screen pixel density = hdpi

Touchscreen type = notouch

Primary text input method = 12key

我们拥有的资源是这样:

drawable/

drawable-en/

drawable-fr-rCA/

drawable-en-port/

drawable-en-notouch-12key/

drawable-port-ldpi/

drawable-port-notouch-12key/

那么Android会选择哪个呢?
先说答案, 是drawable-en-port. Android 选择的逻辑是这样的:

1.      消除不兼容的, 有矛盾的资源文件, 资源中的drawable-fr-rCA/就是, 它跟en-GB冲突了. 由于DPI类的修饰符并不要求跟资源精确匹配, 所以drawable-port-ldpi并不算冲突项.

2.      逐项检查修饰符表格, 看是否有配置项符合表格中的项. 在查到语言和区域的时候, 会发现en-GB的存在, 这时候Android会去掉不包含en的项. 那么drawable-fr-rCA/, drawable-port-ldpi/, drawable-port-notouch-12key/就被排除了.

3.      然后到屏幕方向的时候, 通过port可以排除drawable-en-notouch-12key/和drawable-port-notouch-12key/.那么就锁定了drawable-en-port/.

虽然notouch-12key符合要求, 但是由于排查顺序严格要求按照修饰符的表格顺序, 那么由于port的存在, drawable-en-notouch-12key需要排除.


参考:  http://developer.android.com/guide/topics/resources/providing-resources.html

你可能感兴趣的:(Android,基础)