在android开发过程中,总需要用到各种各样的图片,string等资源,为了便于管理,android将资源统一置于res文件中,本文将对android官方文档和作者的一些心得做一些总结。
一 资源概述
Android开发时,开发者将所有的资源位于res/下,在构建时,工具(如aapt)会将所有资源进行打包处理(google文档中是这么描述的:The Android SDK tools compile your application's resources into the application binary at build time.) ,便于之后对资源的访问。
二 R类概述
Android sdk对程序进行编译时,aapt将所有的位于res/目录下的资源自动生成一个标识,可以理解为系统为了更快的找到资源,对所有的资源编了号,即每个资源自动生成一个ID,并将所有的资源ID编入R类中,便于访问。即R类中的所有域都是ID,都是int类型的。要想获取一个资源ID,通过类似R.drawable.id既可以获取到资源的id,之后可以利用该id对资源进行具体操作。
三 访问资源
对于android中的资源,我们总是要访问的,系统既然为我们对所有的资源都编了号码。我们就用这个号码对资源进行访问,访问方式有两种。
假如我们有一个string资源,
<resources>
<string name="hello">hello, world</string>
</resources>
1 在代码(Code)中
利用资源ID,如
textView.setText(R.string.hello);
在上面的例子中,我们设置一个图片资源时,只要将图片的ID传入即可。
2 在xml文件中
在xml中访问资源更加简单,只要用@string/hello即可。
四 Resources类概述
Resources类并不是一个资源,而是资源操作的工具类,有点像Utils类。在Resources类中,包含了访问各种资源的方法。在android中,我们只需要获取到资源的ID,剩下的事情一般其实都是交予Resources去完成的,Resources会根据不同的资源类型和资源ID去获取资源,从而对资源进行各种操作。
用一个textview作简单说明,现有加入在activity中需要对一个Text设置text,需要作如下的操作。
text.setText(R.string.login_success);
这时,我们看一下setText(int)这个函数的源码,如下:
public final void setText(@StringRes int resid) {
setText(getContext().getResources().getText(resid));
}
源码中可以看到,首先从Context(这里就是当前的activity了)中通过getResources()获取到Resources类的实例,然后根据提供的string类型的资源id,获取到该string,从而对textview进行赋值。
五 资源分类
res/下有多种资源,如图片,布局文件等,为了便于管理,对资源进行了分类。每种资源都放置在特定的文件夹下,如res/drawable/中存放的都是drawable类型的资源。该类型的资源在系统运行都要转成java对象进行操作,例如每个res/drawable文件的资源都会被转成Drawable类的对象。每个资源文件都可以在java和xml中访问。
在res/下,values是一个特殊的文件夹,res/values可以保存多种简单资源,比如colors,strings等。为了区分,可以在res/values下建立多个文件分别存储不同的资源,比如colors.xml保存color资源,strings.xml保存string资源。比如对colors.xml可以保存颜色。
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="color_name" >hex_color</color>
</resources>
对于 strings 可以保存字符串
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="string_name">text_string</string>
</resources>
当然,在res/values中可以混合所有的简单资源,在一个xml文件中,可以同时声明string 和 color资源。
在R类中对不同种类资源的ID,用子类进行了划分,比如所有drawable类型的资源ID,都在R类中的drawable子类中。在xml文件中访问时,通过@/drawable/name的形式访问,在java中,通过R.drawable.id获取资源的id,从而利用Resources操作id。
在R这个类中,有所有的资源id,每种资源对应一个内部类,简单示例如下:
public final Class R{
public static final Class attr{
}
public static final Class color{
public static final int lightgrey=0x7f0b0020;
}
}
需要获取color类型的资源时,需要利用R.color.lightgreay既可以获取到该颜色资源的ID。
由于android资源种类繁多,有的资源又能分成许多子类,因此本文只选取部分内容进行讲解,希望能够举一反三,触类旁通。
1 drawable 资源
所有置于res/drawable/文件夹下的资源都是drawable类型资源。顾名思义,这种资源一般都是图像性质的。
在R类中,用子类drawable保存所有的drawable类型资源的ID,可以按照R.drawable.id形式获取该类资源的ID。每个资源在java中都是一个Drawable类,注意,R类中的子类是drawable,java中是Drawable类,前者保存资源的ID,后者是资源本身。
Drawable资源其实是一类资源的统称,又分成了多种子类,在java中每种drawable资源都对应一个Drawable类的子类。我这里用一个类图展示所有的子类,如图1。但是对所有的Drawable资源都可以用Resouce.getDrawable(int)进行访问。
图1 Drawable 类图
上图所示中的每个Drawable子类都对应一种特定的drawable资源,这里就简单说一下:
(1) BitmapDrawable 就对应一个png文件。
(2) NinePatchDrawable 就对应一个.9文件。
在java中例如对imageview操作时,就可以利用drawable资源的ID进行。
ImageView iv = new ImageView(this);
iv.setImageResource(R.drawable.actionbar_selector_back_icon);
(3) StateListDrawable 就是一个selector,对不同状态的控件进行不同的展示。在一个xml文件中,对不同状态需要的drawable对象进行声明。
在java中,通过R.drawable.file_name获取资源ID,在xml中通过@drawable/file_name获取资源。
Xml文件遵循如下规则:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android"
android:constantSize=["true" | "false"]
android:dither=["true" | "false"]
android:variablePadding=["true" | "false"] >
<item
android:drawable="@[package:]drawable/drawable_resource"
android:state_pressed=["true" | "false"]
android:state_focused=["true" | "false"]
android:state_hovered=["true" | "false"]
android:state_selected=["true" | "false"]
android:state_checkable=["true" | "false"]
android:state_checked=["true" | "false"]
android:state_enabled=["true" | "false"]
android:state_activated=["true" | "false"]
android:state_window_focused=["true" | "false"] />
</selector>
此外drawable资源还有其他种类,暂时没有研究,这里不做描述。
2 Color State List 资源
Colorstatelist 是一个根据View的状态对颜色进行选择的xml文件。
所有的color state list 资源保存在res/color/目录下,每一个资源文件都对应一个ColorStateList对象。
在java中访问时利用R.color.file_name
在xml中利用@color/file_name
!!!!!!!注意,这里和values文件下的color资源访问方式一样,但是这是两种资源,一种是color资源,一种是ColorStateList资源,在java中也是两种不同的对象。
另外,Color资源也能用在drawable资源中,如
android:drawable="@color/green"
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android" >
<item
android:color="hex_color"
android:state_pressed=["true" | "false"]
android:state_focused=["true" | "false"]
android:state_selected=["true" | "false"]
android:state_checkable=["true" | "false"]
android:state_checked=["true" | "false"]
android:state_enabled=["true" | "false"]
android:state_window_focused=["true" | "false"] />
</selector>
六 其他
访问平台资源
Android包含一系列标准资源,在访问时,要加上包名:
如android.R.simple_list