android resource(应用资源)总结
android的应用资源包括动画,图像,字符串,布局文件等等,所有的资源文件都存放在app/src/res目录下。但是,需要注意的是,不同的文件类型需要放在不同的资源目录下,对应的资源目录的名称也不相同。如存放图片的目录是drawable目录;存放布局文件的目录是layout目录等等。下面具体介绍关于android应用资源的相关知识要点
-
资源类型及其对应的文件目录名称:(以下目录都是存放在路径:app/src/res/目录下)
animator目录:属性动画的xml文件(Property Animation)
anim目录:补间动画的xml文件(Tween animation)
color目录:颜色状态列表的 XML 文件,即View处在不同状态对应不同的颜色的xml文件
drawable目录:.png图片,.jpg图片,drawable类型的xml文件等等
mipmap目录:不同启动器图标密度的可绘制文件
layout目录:用户定义界面布局的文件
menu目录:菜单资源文件
raw目录:以原始格式保存的任意文件。要使用Raw打开这些资源 InputStream,请Resources.openRawResource()使用资源ID(如R.raw.xxx)调用。如mResources.openRawResource(R.raw.filename)
values目录:包含简单值(例如字符串,整数和颜色)的XML文件。如string.xml,color.xml,dimen.xml,style.xml,attr.xml文件等等
font目录:字体格式文件,如.ttf .otf .ttc等文件。编译后可以通过R.font.abc(java代码中)或者@font/abc(xml文件中)去访问
Q:上面讲到的raw目录可以存放所有类型的任意文件,那么android为何还要提供assert目录(路径:app/src/,和res、java、AndroidManifest.xml同一级目录)?
A:res/raw目录和assert目录的区别主要有以下几点:
1、res目录下的文件都是可以被编译的资源文件,即系统在编译apk的时候,能在R.java文件中生成对应的该资源的id。由于raw文件res目录下,所以也能在R.java生成对应的id。而assert目录是跟res目录平级的,所以不会生成对应的id,即在编译阶段,不会编译assert目录下的文件。
2、res目录下只能存放文件,不能存放目录。实际上,所有res目录下,都是存放对应的资源类型目录(如raw | drawable | string | anim | animation等等)。而assert目录下是可以存放子目录的,然后通过context.getAssert()方法可以拿到assert目录对应的指针对象,之后就可以对整个assert目录进行操作
3、mResources.openRawResource(R.raw.×××)访问raw目录下的文件资源时,拿到的是对应的文件的字节流inputStream。而通过context.gerAssert()方法拿到的是assert整个目录对象,可以通过context.getAssert().list(Path)列出对应的目录下的所有文件
4、res/raw目录和assert目录唯一的相同点是:只能对其目录下的文件进行读操作,没有写权限。两者目录下的文件在打包后会原封不动的保存在apk包中,不会被编译成二进制,即不会存放在data\data\yourApp目录下。 -
android系统设计的时候,是将资源(如UI布局,动画资源,音频资源等等)和源代码分离开的。这样的设计,带来了两个好处。具体如下:
1、整个项目的结构更加清晰。源代码专注于实现对应的功能;资源专注于提供素材。这样对后期的维护提供了非常便利的先天条件
2、可以提供适用于不同设备配置的备用资源,如:为720p的屏幕提供一套布局,为1080p的屏幕提供另一套布局。这是安卓APP的最基础的两大特性(提供多个入口点;兼容不同的设备)之一 -
为设备提供兼容性资源的方法
1、android兼容性资源的匹配是通过目录名称来实现的,所以对应的资源目录的名称是核心关键。具体格式为:在res/以形式创建一个名为 <resources_name>-<qualifier> 的新目录。
<resources_name>:是相应的默认资源的目录名(对应的类型名称在(1)知识点)
<qualifier>:是一个配置修饰符,用于指定要使用这些资源的单个配置,如果需要配置多个<qualifier>,那么用破折号"-"隔开。对应修饰符的链接地址
2、"兼容性资源目录"一定是跟"默认资源目录"在同一目录下,并且是平级的。具体是:都在app/src/res/目录下。如app/src/res/drawable-hdpi目录和app/src/res/drawable目录
3、"兼容性资源目录"的名称不区分大小写,资源编译器在编译资源的时候会将目录名称全部转化为小写,然后再去匹配对应的规则
4、"兼容行资源目录"的名称中"修饰符"的顺序一定要严格按照顺序来,具体的顺序依据官方提供的标准来
(链接地址),如:错误: drawable-hdpi-port/ 正确: drawable-port-hdpi/ 原因:官方定义的"屏幕方向"(port)的优先级比"屏幕密度"(hdpi)的优先级高,所以port修饰符一定要排在hdpi前面 -
系统兼容性资源的匹配规则:
1、遍历所有与限定符相关的配置
2、根据遍历得到的所有相关配置,将"兼容性资源"中所有与配置矛盾的资源文件全部排除掉
3、根据官方提供的修饰符列表中的"修饰符"优先级,开始匹配特定的修饰符
(1) 如果有资源目录包含该修饰符,则将其他所有不包含该修饰符的资源目录排除掉
(2) 如果没有资源目录包含该修饰符,则继续寻找下个优先级的修饰符
4、重复步骤(2),(3),直到只剩下一个资源目录
具体例子:
资源目录:
drawable/
drawable-en/
drawable-fr-rCA/ -- 3
drawable-en-land/ -- 4
drawable-en-port/ -- 5
drawable-en-notouch-12key/ -- 6
drawable-port-ldpi/ -- 7
drawable-port-notouch-12key/ -- 8
设备配置:
Locale = en-GB -- 1
Screen orientation = port -- 2
Screen pixel density = hdpi -- 3
Touchscreen type = notouch -- 4
Primary text input method = 12key -- 5
开始匹配
步骤1:语音类型是en,所以3会被排除;屏幕方向是port,所以4会被排除,所以第一步骤设备所有配置,就排除了两个资源目录drawable-fr-rCA/和drawable-en-land/
步骤2:匹配语言en,因为5包含了en,所以将所有不包含修饰符en的目录排除,所以1、6、7、8会被排除
步骤3:重复步骤2,匹配区域GB,由于只剩下2和5,并且2和5不包含区域修饰符,所以继续匹配下一个修饰符
步骤4:下一个修饰符是方向port,由于5包含了port修饰符,所以排除不包含port修饰符的2
经过以上步骤,最后只剩下5符合规则,所以该设备的兼容性资源会选择5--drawable-en-port -
访问资源的方式
1、在java代码中访问;具体通过编译生成的R.java文件对应的索引去寻找对应的资源。例子:R.string.hello
2、在xml文件中访问;具体格式为@String/hello -
创建别名资源(这篇博客写的很好)
1、对于图片,可以创建一个xml文件,然后在xml文件中通过bitmap节点引用到特定的图片。如:
<?xml version="1.0" encoding="utf-8"?>
<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
android:src="@drawable/icon_ca" />
2、布局文件,通过创建xml文件,然后在xml文件中通过merge节点引用其他布局文件,如:
<?xml version="1.0" encoding="utf-8"?>
<merge>
<include layout="@layout/main_ltr"/>
</merge>
3、字符串及其他简单值:只需要将所需字符串的资源ID用作新字符串的值,对于颜色等其他简单值属性,也是一样的
<?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="red">#f00</color>
<color name="highlight">@color/red</color>
</resources>