现在的位置: 首页 > 综合 > 正文

Android 资源(resource)学习小结

2012年08月02日 ⁄ 综合 ⁄ 共 14485字 ⁄ 字号 评论关闭

运用Android SDK进行UI开发时,虽然也可以使用纯代码来完成,但是那种方法对我这种刚学习Android对API还不懂的人来说,能进行类似VB、MFC一样图形化开发自然是最合适不过的。幸好Android也提供了这种方式,在Android工程文件中专门有个res目录用于存放资源,该目录下的资源可以进行可视化的编辑,编写好的资源通过AAPT(Android AssetPackaging
Tool)工具自动生成gen目录下的R.java资源索引文件,之后在Java代码和XML资源文件中就可以利用索引来调用资源了。

Android提供了如此便利的资源架构,要想使用它,还是要对他有深入的了解才可以,以下就这阵子对Android资源的学习进行小结来回顾和整理几个问题

Android资源目录结构问题?

Android资源支持哪些类型资源,他们具体的语法和使用规则?

Android资源目录结构

Android资源除了assets目录是与res同级外,其它资源均被放在res/目录下面,该目录下面的资源文件夹并不是随意命名的,需要遵循严格的规范,否则编译生成R.java过程中会报类似“invalidresource directory name **”的错误提示,并且导致R.java自动生成失败。

常用的缺省目录和对应资源类型在SDK帮助中有表格列出,简单摘抄如下

目录Directory

资源类型Resource Types

res/animator

存放定义了property animations(android 3.0新定义的动画框架)的XML文件

res/anim/

存放定义了补间动画(tweened animation)或逐帧动画(frame by frame animation)的XML文件。(该目录下也可以存放定义property animations的XML文件,但是最好还是分开存放)

res/raw/

存放直接复制到设备中的任意文件。它们无需编译,添加到你的应用程序编译产生的压缩文件中。要使用这些资源,可以调用Resources.openRawResource(),参数是资源的ID,即R.raw.somefilename

res/drawable/

存放能转换为绘制资源(Drawable Resource)的位图文件(后缀为.png, .9.png, .jpg, .gif的图像文件)或者定义了绘制资源的XML文件

res/color/

存放定义了颜色状态列表资源(Color State List Resource)的XML文件

res/layout/

存放定义了用户界面布局的XML文件

res/menu/

存放定义了应用程序菜单资源的XML文件

res/values/

存放定义了多种类型资源的XML文件

这些资源的类型可以是字符串,数据,颜色、尺寸、样式等等,具体在后面详述

res/xml/

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

资源文件夹内文件夹命名规则

上面说过res文件夹下的文件夹命名是有规矩的,否则会报类似“invalidresource directory name **”的错误提示,除了上表提供的缺省文件夹,一般可以用缺省文件夹名加短横线加配置相关的限定符构成需要的资源文件夹,用于区别不同屏幕分辨率、不同机型特点(是否带键盘等)以及不同的本地化资源等用处,详细参考API说明文档。具体案例如下图所示

 

其中的values-zh-rCN就是中文简体资源包,用于本地化,至于其它就对照API说明文档来分析。一般项目缺省的资源文件夹名称就够了。

资源文件夹内的资源文件存放规则

由上面资源表可知,每个文件夹中存放的文件类型不仅有规定,而且对文件内容也是有严格要求的,曾经将一个定义布局的spinner.xml文件放置在res/values,结果就报“Invalid start tag *Layout spinner.xml”错误,并导致R.java没有生成;将该布局文件放置在res/color下面,虽然没有报错,但是原本的布局文件,不再是正确生成为形如“R.layout.spinner”的布局资源,而是生成为了“R.color.spinner”的颜色资源索引,具体如下所示

布局文件放置正确的R.java中代码

   public static final class layout {

       public static final int autocomplete=0x7f030000;

       public static final int spinner=0x7f03000d;

   }

布局文件放置错误的R.java中代码

   public static final class color {

       public static final int solid_blue=0x7f050001;

       public static final int spinner=0x7f050004;

   }

另外当一种资源定义XML文件放在不对应的res文件夹下,在可视化环境下,也就不能正确显示和编辑。

通过上述一些特性,我们可以猜测出android的aapt工具的工作原理,先是根据文件夹名来进行对资源文件和XML文件进行不同的解析和编译规则进行解析和编译,ADT工具也是根据具体文件夹名称调用不同的规则来可视化编辑和呈现。

使用eclipse IDE提供的框架来创建资源

由于Android资源文件和文件夹有那么多的规矩,所以新手还是建议用eclipseIDE提供的创建XML文件的框架来创建资源文件和资源文件夹即在你需要创建资源文件时,通过“File”“New”“Android XML file”就可以弹出如下的New Android XML File对话框,

选好工程,填好资源文件名,在“What type of resourcewould you like to create”中勾选需要创建的资源类型,假如是非缺省目录资源就在“what type of resource configuration would you like?”添加需要的配置类型,就可以在“Folder”中自动生成资源xml所在的文件夹,这个不用修改它。其它就根据需要来选择,然后点击“Finish”,就可以创建出符合规则的资源文件了。在这里需要注意的是资源文件名不能使用大写字母。

是不是很省事,又能做出正确的事情啊,呵呵!

Android资源类型及其简单使用

上面对Android的资源目录的分析中,已经大致展现了Android资源类型的大致脉络,下面从简单资源先入手详细罗列下具体的资源类型和使用。一般而言,没有明说资源不能在XML资源文件中调用,那么该资源都是既可以在其它XML资源文件中调用又可以在Java代码中调用的。

字符串常量资源(string)

字符串资源位于/res/values目录下,一般定义为/res/values/strings.xml文件中(文件名随意,但是目录是固定的),主要定义的是应用程序需要用到的字串资源,这和Symbian的字串资源规划类似,不过更加进步了些。当然,你非要在代码中使用字串也可以,但那种方式并不是推荐的。字串资源有String、String Array和Quantity Strings (Plurals)三类,其各自语法和用例稍微有些区别

String语法

<?xml version="1.0"encoding="utf-8"?>

<resources>

  <string name="string_name">text_string</string>

</resources>

上面的string_name字符串资源,可以通过如下两种方法调用

XML资源定义中

@[package:]string/string_name

Java代码中

R.string.string_name

String用例

假设有个资源文件为res/values/strings.xml,其内容如下:

<?xml version="1.0"encoding="utf-8"?>

<resources>

   <string name="hello">Hello!</string>

</resources>

那么这个hello字串资源在其它XML资源文件中的调用如下所示

<TextView

   android:layout_width="fill_parent"

   android:layout_height="wrap_content"

   android:text="@string/hello"/>

在java代码中的调用如下

String string = getString(R.string.hello);

String Array的语法

<?xml version="1.0"encoding="utf-8"?>

<resources>

   <string-array name="string_array_name">

       <item>text_string</item>

   </string-array>

</resources>

上面的string_array_name字符串资源,可以通过如下两种方法调用

XML资源定义中

@[package:]array/string_array_name

Java代码中

R.array.string_array_name

String Array用例

假设有个String Array资源在/res/values/stringArray.xml中,内容如下

<?xml version="1.0"encoding="utf-8"?>

<resources>

   <string-array name="planets_array">

       <item>Mercury</item>

       <item>Venus</item>

       <item>Earth</item>

       <item>Mars</item>

   </string-array>

</resources>

那么在其它资源XML文件中,假设有个下拉列表需要用到上面的字符串数组资源,则可以如下调用

<Spinnerandroid:id="@+id/spinner1"

       android:layout_width="fill_parent"

       android:layout_height="wrap_content"

       android:entries="@array/planets_array">

</Spinner>

在Java代码中的调用示例如下

Resources res = getResources();

String[] planets = res.getStringArray(R.array.planets_array);

Quantity Strings语法

<?xml version="1.0"encoding="utf-8"?>

<resources>

   <plurals name="plural_name">

       <item quantity=["zero" | "one" | "two"| "few" | "many" |"other"]>text_string</item>

   </plurals>

</resources>

帮助文档中没有给出XML资源文件中对其的使用方法,也没有明确说不能通过XML调用,我也没有搞明白这个资源,所以暂时只给出Java代码中对上述plural_name资源的调用情况

R.plurals.plural_name

其中关于zero、one、two、few和many在帮助文档中有详细的释义,这里就不单独罗列。

Quantity Strings用例

假设有个Quantity Strings资源定义在/res/values/stringQuantity.xml中,内容如下

<?xml version="1.0"encoding="utf-8"?><resources>

  <plurals name="numberOfSongsAvailable">

       <item quantity="one">One song found.</item>

       <item quantity="other">%d songs found.</item>

   </plurals>

</resources>

由于这个资源,我还不太会用,所以只好照抄帮助文档的使用,至于XML文档中如何使用还不会,在Java代码中使用如下所示

int count = getNumberOfsongsAvailable();

Resources res = getResources();

String songsFound = res.getQuantityString(R.plurals.numberOfSongsAvailable, count, count);

String资源的注意项

Android字符串定义时,假如有特殊字符,而没有用到转义字符,就必须用双引号将字符串完全包住,具体如下所示

//正确使用方法

<stringname="good_example">"This'll work"</string>

<stringname="good_example_2">This\'ll also work</string>     

//错误

<stringname="bad_example">This won't work!</string>

//错误不可使用html转义字符

<stringname="bad_example_2">This won&apos;t work!</string>

由上可知,虽然字符串支持HTML标记,但是不支持html的转义字符。另外对于带格式/风格的字符串资源,也是不能在XML代码中调用,只能在Java代码中使用,而且使用过程中有点复杂,需要用htmlEncode解析,然后用String.format()来实现赋值,接着用fromHtml(String)得到格式化后的string。具体帮助文档给出的用例如下

XML资源定义如下:

<resources>

 <string name="welcome_messages">Hello, %1$s! You have&lt;b>%2$d new messages&lt;/b>.</string>

</resources>

Java代码调用如下:

String escapedUsername = TextUtil.htmlEncode(username);

Resources res = getResources();

String text = String.format(res.getString(R.string.welcome_messages), escapedUsername,mailCount);

CharSequence styledText = Html.fromHtml(text);

整数常量资源(Integers)

整数常量在C/C++通常是放在代码里面,android将整型常量、Bool常量和数组常量等等都可以放到XML资源文件中,后面具体介绍这些资源时就不再做展开了。一般整数常量被放置在/res/values/integers.xml中,同样文件名可以随意,但是目录必须固定在/res/values/下

Integer语法

<?xml version="1.0"encoding="utf-8"?>

<resources>

   <integer name="integer_name">integer</integer>

</resources>

上面的integer_name整数常量,可以通过如下两种方法调用

XML资源定义中

@[package:]integer/integer_name

Java代码中

R.integer.integer_name

Integer用例

假设整数常量放置在/res/values/integers.xml中,内容如下

<?xml version="1.0"encoding="utf-8"?>

<resources>

   <integer name="max_speed">75</integer>

   <integer name="min_speed">5</integer>

</resources>

我们在代码中使用的时候,通过以下方式进行调用

Resources res = getResources();

int maxSpeed = res.getInteger(R.integer.max_speed);

Integer Array语法

<?xml version="1.0"encoding="utf-8"?>

<resources>

   <integer-array name="integer_array_name">

       <item>integer</item>

   </integer-array>

</resources>

上面定义的integer_array_name可以用如下两种方法调用

XML资源定义中

@[package:]array.integer_array_name

Java代码中

R.array.integer_array_name

Integer Array用例

假设整数数组放置在/res/values/intergers.xml中,内容如下所示

<?xml version="1.0"encoding="utf-8"?>

<resources>

   <integer-array name="bits">

       <item>4</item>

       <item>8</item>

       <item>16</item>

       <item>32</item>

    </integer-array>

</resources>

该资源在java代码中的调用为

Resources res = getResources();

int[] bits =res.getIntArray(R.array.bits);

Typed Array常量资源

Typed Array资源有点类似于Symbian中瘦模板类的,用于存放多种不同类型资源数组的资源,本来想将这个资源放后面讲解,但是前面提供了一系列数组案例,就一并将这个数组也提前罗列下吧。该资源一般放置于/res/values/arrays.xml中

Typed Array语法

<?xml version="1.0"encoding="utf-8"?>

<resources>

   <array name="typed_array_name">

       <item>resource</item>

   </array>

</resources>

上面的typed_array_name资源,可以通过如下两种方法调用

XML资源定义中

@[package:]array/typed_array_name

Java代码中

R.array.array_name

Typed Array用例

假设有两个Typed Array资源定义在/res/values/arrays.xml中,具体如下

<?xml version="1.0"encoding="utf-8"?>

<resources>

   <array name="icons">

       <item>@drawable/home</item>

       <item>@drawable/settings</item>

       <item>@drawable/logout</item>

   </array>

   <array name="colors">

       <item>#FFFF0000</item>

       <item>#FF00FF00</item>

       <item>#FF0000FF</item>

   </array>

</resources>

该资源通过以下方法在java代码中调用

Resources res = getResources();

TypedArray icons = res.obtainTypedArray(R.array.icons);

Drawable drawable = icons.getDrawable(0);

TypedArray colors = res.obtainTypedArray(R.array.icons);

int color = colors.getColor(0,0);

由于每一种类型都是通过不同的API来获取数组中的元素,比如上面用例里面color用int getColor(int index, intdefValue)函数,Drawable用Drawable getDrawable(int index)函数,至于其它相关的类型该调用什么函数来获取具体可以参看android.content.res.TypedArray的源码文件\frameworks\base\core\java\android\content\res\TypedArray.java来获得更多的详情。

布尔常量资源(bool)

该资源一般定义在/res/values/bools.xml中。

bool语法

<?xml version="1.0"encoding="utf-8"?>

<resources>

   <bool name="bool_name">[true| false]</bool>

</resources>

上面的bool_name布尔常量资源,可以通过如下两种方法调用

XML资源定义中

@[package:]bool/bool_name

Java代码中

R.bool.bool_name

bool资源用例

假设有bool常量资源定义在res/values/bools.xml中,内容如下

<?xml version="1.0"encoding="utf-8"?>

<resources>

   <bool name="screen_small">true</bool>

   <bool name="adjust_view_bounds">true</bool>

</resources>

那么在xml资源中的调用可以如下

<ImageView

   android:layout_height="fill_parent"

   android:layout_width="fill_parent"

   android:src="@drawable/logo"

   android:adjustViewBounds="@bool/adjust_view_bounds"/>

在Java代码中的调用如下

Resources res = getResources();

boolean screenIsSmall = res.getBoolean(R.bool.screen_small);

Dimension常量资源

该资源定义跟屏幕显示相关的一些尺寸常量,一般保存在/res/values/dimen.xml文件中

具体的度量单位有:

px(象素): 屏幕实际的象素,常说的分辨率1024*768pixels,就是横向1024px, 纵向768px,不同设备显示效果相同。

in(英寸): 屏幕的物理尺寸, 每英寸等于2.54厘米。

mm(毫米): 屏幕的物理尺寸。

pt(点): 屏幕的物理尺寸。1/72英寸。

dp/dip: 与密度无关的象素,一种基于屏幕密度的抽象单位。在每英寸160点的显示器上,1dp =1px。但dp和px的比例会随着屏幕密度的变化而改变,不同设备有不同的显示效果。

sp: 与刻度无关的象素,主要用于字体显示best for textsize,作为和文字相关大小单位。

dimension资源定义语法

<?xml version="1.0"encoding="utf-8"?>

<resources>

   <dimen name="dimension_name">dimension</dimen>

</resources>

dimension资源用例

假设定义了一个dimen资源在res/values/dimens.xml文件中

<?xml version="1.0"encoding="utf-8"?>

<resources>

   <dimen name="textview_height">25dp</dimen>

   <dimen name="textview_width">150dp</dimen>

   <dimen name="ball_radius">30dp</dimen>

   <dimen name="font_size">16sp</dimen>

</resources>

我们可以在XML资源中进行如下调用

<TextView

   android:layout_height="@dimen/textview_height"

   android:layout_width="@dimen/textview_width"

   android:textSize="@dimen/font_size"/>

在Java代码中进行如下调用

Resources res = getResources();

float fontSize = res.getDimension(R.dimen.font_size);

颜色常量资源(color)

颜色常量通常被定义在/res/values/colors.xml文件内,同时颜色资源作为一种可绘制的资源,也可以被定义在/res/drawable/文件夹下,调用方式也完全不同,在这里只介绍作为常量的颜色资源。虽然两种定义和调用方式不同,但是颜色的数值表现形式却是一样的,都是形如下面的十六进制格式(后面涉及颜色数值就不再赘述了)

#RGB

#ARGB

#RRGGBB

#AARRGGBB

比如#f00表示不透明的12位红色,而#80ff0000表示透明的32位真彩红色

颜色常量语法

<?xml version="1.0"encoding="utf-8"?>

<resources>

   <color name="color_name">hex_color</color>

</resources>

上面的color_name颜色常量可以通过如下两种方法调用

XML资源定义中

@[package:]color/color_name

Java代码中

R.color.color_name

颜色常量用例

假设有颜色常量被定义在res/values/colors.xml中

<?xml version="1.0"encoding="utf-8"?>

<resources>

  <color name="opaque_red">#f00</color>

  <color name="translucent_red">#80ff0000</color>

</resources>

在XML要使用该常量资源,可以通过如下方法

<TextView

   android:layout_width="fill_parent"

   android:layout_height="wrap_content"

   android:textColor="@color/translucent_red"

   android:text="Hello"/>

在Java代码中如果想使用该资源,则如下调用

Resources res = getResources();

int color = res.getColor(R.color.opaque_red);

至此我们将res/values下面定义的资源类型除了风格(Style)和主题(Theme)资源外,全部都介绍过了,由于风格和主题案例需要设计布局(layout)和View等,所以最后再涉及这两类资源的介绍。

状态颜色列表资源(color state list)

该资源被放置于/res/color/目录下面,用来定义一个类似Button控件在不同状态下需要呈现不同的颜色。因此这种XML资源文件描述的是跟控件状态相挂钩的颜色状态,具体见下面语法

状态颜色列表资源语法

假如有个状态颜色列表资源文件res/color/colorstatefile.xml

<?xml version="1.0"encoding="utf-8"?>

<selectorxmlns: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>

该菜单资源可以通过如下渠道访问

XML资源定义中

@[package:]color/ colorstatefile

Java代码中

R.color. colorstatefile

状态颜色列表资源用例

有一个定义了button状态颜色列表的资源res/color/button_text.xml

<?xml version="1.0"encoding="utf-8"?>

<selectorxmlns:android="http://schemas.android.com/apk/res/android">

   <item android:state_pressed="true"android:color="#ffff0000"/> <!-- pressed -->

   <item android:state_focused="true"android:color="#ff0000ff"/> <!-- focused -->

   <item android:color="#ff000000"/> <!-- default -->

</selector>

则在布局文件中一个Button控件需要使用该状态颜色,就可以通过如下调用

<Button

   android:layout_width="fill_parent"

   android:layout_height="wrap_content"

   android:text="@string/button_text"

   android:textColor="@color/button_text"/>

布局资源(Layout)

布局资源是放置于/res/layout/下面的用于定义UI界面的XML文件,该资源被用于Activity或者其他UI组件。由于我在学习android之前,没有过Java GUI开发的经验,所以不清楚Java里面的UI设计思想,只知道Android UI类都是基于View和ViewGroup两个类,View类的子类就是“widget”即类似文本框、编辑框等UI控件,ViewGroup的子类就是“Layout”即LinearLayout、RelativeLayout等布局容器类。布局容器类里面可以布局UI控件和其它布局容器对象。具体结构如下所示

这和Symbian里面控件和视图概念有些区别,Symbian里面所有的UI类都是派生自CCoeControl,即一个控件可以成为另一个控件的容器。在Android中容器就是容器,控件就是控件,只不过容器中除了能放置控件外,也能放置容器,这为我们创建自有复杂的界面提供了条件。

Android提供了多种布局类型,列表如下

布局类型

布局标签

说明

线性布局

LinearLayout

按照垂直或水平方向布置控件,每行或列只能放置一个控件

帧布局

FrameLayout

从屏幕左上角布置控件,不能控制位置,多个控件会叠加放置

相对布局

RelativeLayout

布局内的view组件元素按照依赖关系相对位置来放置,位置计算只执行一次,因此必须按依赖反向安排组件顺序

绝对布局

AbsoluteLayout

按照绝对坐标(即x,y)来布局控件(相对用的不多)

表格布局

TableLayout

按照行列方式布局控件,类似于HTML里的Table

切换卡

TabWidget

实现标签切换的功能,是一个派生自LinearLayout的布局方式

布局资源的语法

<?xml version="1.0"encoding="utf-8"?>

<ViewGroup xmlns:android="http://schemas.android.com/apk/res/android"

   android:id="@[+][package:]id/resource_name"

   android:layout_height=["dimension" | "fill_parent" |"wrap_content"]

   android:layout_width=["dimension" | "fill_parent" |"wrap_content"]

   [ViewGroup-specific attributes] >

   <View android:id="@[+][package:]id/resource_name"

       android:layout_height=["dimension" | "fill_parent" |"wrap_content"]

       android:layout_width=["dimension" | "fill_parent" |"wrap_content"]

       [View-specific attributes] >

       <requestFocus/>

   </View>

   <ViewGroup >

       <View />

   </ViewGroup>

   <include layout="@layout/layout_resource"/>

</ViewGroup>

上面的布局资源文件名为layoutEx.xml,则可以通过如下两种方法调用

在XML资源定义中

@[package:]layout/layoutEx

Java代码中

R.layout.layoutEx

布局资源用例

为了尽可能在在一个例子里面体现更多的布局,为此用例使用如下五个布局文件来关联一个Activity

第一个布局文件为简单的相对布局,其文件名为right.xml,内容如下

<?xml version="1.0"encoding="utf-8"?>

<RelativeLayoutandroid:id="@+id/right"

       xmlns:android="http://schemas.android.com/apk/res/android"

       android:layout_width="fill_parent"

       android:layout_height="fill_parent"

       android:padding="10dip"

       >

       <TextViewandroid:id="@+id/right_view1"

抱歉!评论已关闭.