Android Resource篇--- I 存放资源文件的规则
2015-11-20 17:24
344 查看
概述
Resource的含义: 一款优秀的APP不能只包含代码.Resource是指为代码提供服务的其它文件和静态内容, 比如图片, 布局文件, 用户接口字符串等.使用Resource的好处: 可以将资源跟代码分离, 更便于独立管理. 并且可以大大提高不同配置下APP的适应性, 比如不同的屏幕尺寸, 不同的语言等.
Resource典型的应用场景: 每种Resource都支持默认和多个备选资源,默认资源用于一般情况(没有特殊的配置), 备选资源一般用于指定的配置. Resource通过/res下文件夹的名字来区分它们.栗子:
如果我们不使用指定的Resource, 只有一种默认Resource, 那么当APP运行在不同配置的设备上的时候, 就会不加区分的显示成同一个样子:
这显然不怎么合理, 为了应对这样的场景, 我们为横向设备指定了特殊的Resource, 在/res/layout-land/目录下增加布局文件, 那么在不同设备上, 就会显示的合理得多:
制作资源文件
Resource们都在哪:
在一个Android工程中, 所有的Resource文件都放在/res目录下, 一个典型的工程目录大概长这样: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目录提供备选的资源文件呢? 假如我们已经有了一份默认的资源文件, 它们长这样:这时候我们还需要一份为高密度屏(可以理解为某一指定尺寸的屏)准备一份特殊的资源, 那么我们必须提供一份额外的资源文件:
只需要在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是默认的. 在一些特殊的语言中会用到, 比如波斯语和希伯来语, 它们的书写方向是从右向左的. |
最小宽度 | 格式:sw<N>dp 如: sw320dp, sw720dp | 无论屏幕是横屏还是竖屏, 这里的宽度指的都是屏幕的”较短边”, 通常跟layout配合使用. 比如res/layout-sw600dp/意思是此目录下的资源用于宽度至少为600dp的设备. 1dp=1/160英寸. |
有效宽度 | 格式:w<N>dp 如: w720dp, w1024dp | 指定最小有效屏幕宽度, 单位为dp, 这个值会随着屏幕方向的变化而改变. |
有效高度 | 格式:h<N>dp 如: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/, 这样的目录结构是错误的.
目录名是大小写
abb9
不敏感的, 编译器会自动都转为小写.
每种修饰符类型只支持一个值, 比如不能出现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
相关文章推荐
- 使用C++实现JNI接口需要注意的事项
- Android IPC进程间通讯机制
- Android Manifest 用法
- [转载]Activity中ConfigChanges属性的用法
- Android之获取手机上的图片和视频缩略图thumbnails
- Android之使用Http协议实现文件上传功能
- Android学习笔记(二九):嵌入浏览器
- android string.xml文件中的整型和string型代替
- i-jetty环境搭配与编译
- android之定时器AlarmManager
- android wifi 无线调试
- Android Native 绘图方法
- Android java 与 javascript互访(相互调用)的方法例子
- android 代码实现控件之间的间距
- android FragmentPagerAdapter的“标准”配置
- Android"解决"onTouch和onClick的冲突问题
- android:installLocation简析
- android searchView的关闭事件
- SourceProvider.getJniDirectories