1 Android应用资源简介
Android应用程序主要由两部分内容组成:代码和资源。资源主要就是指那些与UI相关的东西,例如UI布局、字符串和图片等。代码和资源分开可以使得应用程序在运行时根据实际需要来组织UI。这样就可使得应用程序只需要编译一次,就可以支持不同的UI布局。这种特性使得应用程序在运行时可以适应不同的屏幕大小和密度, 以及不同的国家和语言等。
2 Android应用程序资源的分类
Android应用程序资源主要分为两大类,分别是assets和res。
2.1 assets类资源
assets类资源放在工程根目录的assets子目录下,它里面保存的是一些原始的文件,可以以任何方式来进行组织。这些文件最终会被原装不动地打包在 apk文件中。如果我们要在程序中访问这些文件,那么就需要指定文件名来访问。假设在assets目录下有一个名称为filename的文件,那么就可以使用以下代码来访问它:
AssetManager am= getAssets();
InputStream is = assset.open("filename");
2.2 res类资源
res类资源放在工程根目录的res子目录下,它里面保存的文件大多数都会被编译,并且都会被赋予资源ID。这样我们就可以在程序中通过ID来访问res类的资源。res类资源按照不同的用途可以进一步划分为以下9种子类型,分别如下:
@1 animator以XML文件保存在res/animator目录下,用来描述属性动画。
属性动画通过改变对象的属性来实现动画效果,可以通过不断地修改对象的坐标值来实现对象移动动画,也可以不断地修改对象的Alpha通道值来实现对象的渐变效果。
@2 anim资源以XML文件保存在res/anim目录下,用来描述补间动画。
补间动画和属性动画不同,它是在对象的原来形状或者位置的基础上实现一个变换来得到的,可以对对象施加一个旋转变换,就可以获得一个旋转动画,也可以对对象实施一个缩放变换,就可以获得一个缩放动画。从数学上来讲,就是在对象的原来形状或者位置的基础上施加一个变换矩阵来实现动画效果。
注意:动画执行中,对象的属性是始终保持不变的,我们看到的只不过是它的一个变形副本。
@3 color资源以 XML文件保存在res/color目录下,用描述对象颜色状态选择器。我们可以定义一个选择器,规定一个对象在不同状态下显示不同的颜色。对象的状态可以划分为pressed、focused、selected、checkable、checked、enabled和window_focused等7种。
@4 drawable资源以XML或者Bitmap文件保存在res/drawable目录下,用来描述可绘制对象。例如,我们可以在里面放置一些图片(.png, .9.png, .jpg, .gif)来作为程序界面视图的背景图。
注意:保存在这个目录中的Bitmap文件在打包的过程中,可能会被优化的。例如,一个不需要多于256色的真彩色PNG文件可能会被转换成一个只有8位调色板的PNG面板,这样就可以无损地压缩图片,以减少图片所占用的内存资源。
除此之外也可能是编译成如下各种Drawable对象的XML文件:
- BitmapDrawable对象
- NinePatchDrawable对象
- StateListDrawable对象?
- ShapeDrawable对象
- Animation对象
- Drawable的其他个种子类对象
@5 layout资源以XML文件保存在res/layout目录下,用来描述应用程序界面布局。
@6 menu资源以XML文件保存在res/menu目录下,用来描述应用程序菜单。例如,Options Menu、Context Menu和Sub Menu。
@7 raw资源以任意格式的文件保存在res/raw目录下,它们和assets类资源一样,都是原装不动地打包在apk文件中的,但它们会被赋予资源ID,这样我们就可以在程序中通过ID来访问它们。假设在res/raw目录下有一名为filename的文件,并且它在编译的过程,被赋予ID为R.raw.filename,那么就可使用以下代码来访问它:
Resources res = getResources();
InputStream is = res.openRawResource(R.raw.filename);
@8 values 这类资源以XML文件保存在res/values目录下, 一般来说分为六种值,分别保存在以下文件中,如下所示:
- arrays.xml (string-array,int-array) 定义数组资源
- colors.xml 定义颜色资源
- dimens.xml 定义尺寸资源
- strings.xml (integer,bool)定义字符串资源
- styles.xml 定义样式资源
@9 xml 这类资源以XML文件保存在res/xml目录下,一般就是用来描述应用程序的配置信息。
3 资源使用(颜色、字符串、尺寸、数组、资源国际化、layout、menu、自适应不同屏幕资源)
3.1 颜色资源(/res/values目录)
颜色XML文件格式代码如下:
<?xml version="1.0" encoding="utf-8"?>
<resources> //resources根元素
? ?<color name="black" >#000000</color>
//color子元素
</resouces>
颜色定义格式说明:
- #RGB: ? ? R、G、B分别指红绿蓝三原色的值(支持0-f这16个级别)
- #ARGB: ? ?A指透明度,R、G、B分别指红绿蓝三原色的值(支持0-f这16个级别)
- #RRGGBB: ?R、G、B分别指红绿蓝三原色的值(支持0-ff这256个级别)
- #ARRGGBB: A指透明度,R、G、B分别指红绿蓝三原色的值(支持0-ff这256个级别)
引用格式:
- java代码中:R.color.color_name ?(这是一个int型的数据,用于表示资源的地址)
- XML文件中: @color/color_name
获得颜色值的方法
getResources().getColor();//返回一个类似#0000FF格式的颜色值
3.2 字符串资源(/res/values目录)
XML文件格式代码如下:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="here" >StringHere</string>
</resouces>
引用格式:
- java代码中: ?R.string.string_name ?
- XML文件中: ? @string/string_name
获得字符串的方法:
Resources.getString(int);?//返回一个String类型的对象
注意:在控件中setText(int resid)和setText(String string_name)这两个方法都是允许的
3.3 尺寸资源(/res/values目录)
XML文件代码如下:
<dimen name="dimen_name">18dp</dimen>
说明:尺寸值的单位可以是px(像素)或者mm(毫米,实际屏幕尺寸)或dp
引用格式:
- java代码: ? ? R.dimen.dimen_name
- XML文件中: ? ?@dimen/dimen_name
获取尺寸资源方法:
Resources.getDimension(R.dimen.dimen_name);//返回一个float类型的对象
注意:该方法返回值为float类型,而setWidth()参数要求是int类型的,所以需要强制类型转换。
3.4 数组资源(/res/values目录)
3.4.1 数组资源基础
创建数组资源,在values目录下创建arrays.xml文件,然后在在arrays.xml中使用<string-array>或者<integer-array>标签定义数组,xml配置如下所示:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string-array name="languages">
<item>cxx</item>
<item>java </item>
<item>php</item>
<item>xml</item>
<item>html</item>
</string-array>
<integer-array name="reminder_methods_values" translatable="false">
<item>1</item>
<item>2</item>
<item>3</item>
</integer-array>
</resources>
其中:<array>是普通数组,<string-array>定义的是字符数组,<integer-array>是整数数组。
3.4.2 引用数组资源
引用数组资源的方式有两种,代码中引用和xml文件中引用,分别如下:
@1 在java代码中引用
Resources res =getResources();
String[] languages = res.getStringArray(R.array.languages);
String[] reminder_methods = res.getIntArray(R.array.reminder_methods_values);
另外,还可以通过obtainTypedArray(int ResId)该防范获得一个 TypedArray类型的普通数组,该类提供了getXXX(int index)方法来获取指定索引处的数组元素。
@2 在xml中引用(这里以spinner控件为例,因为spinner的entries属性刚好需要数组资源)
<Spinner
? ? android:id="@+id/spinner1"
? ? android:layout_width="match_parent"
? ? android:layout_height="wrap_content"
? ? android:entries="@array/languages"
? />
注意:上面引用的时候是@array。
3.5 资源国际化(/res/drawable-zh-rCN-hdpi目录 & /res/values-语言代码-r-国家代码目录)
@1 字符串国际化:只要在res文件夹下新建对应语言的values文件夹就可以。
Android国际化
使用XML资源文件来管理所有字符串消息。不同values文件夹命名方式为:values-语言代码-r-国家代码,例如values-zh-rCN,values-en-rUS
注意:新建Android项目时,会在res目录下自动创建一个默认语言环境的文件夹values。当某一个资源没有在语言环境的对应的资源集合中找到时,就会使用values下的资源。?若某一个语言环境没有在项目中定义语言环境,那么也会使用values下的资源,是使用XML文件进行资源配置。
@2 图片国际化
在res下新建drawable-zh文件夹,存放中文环境下的图片,再新建 drawable-en 作为英语环境下的图片。关于图片名称解读如下:
在新建Android项目时,会在res目录下自动创建三个默认语言环境的文件夹:drawable-hdpi | drawable-ldpi | drawable-mdpi 分别用于存放高、中、低分辨率的图片。Android 系统会根据手机的分辨率自动从不同的对应的某一个文件夹下去加载图片。?同样,它们也可以国际化,命名规则为:drawable-语言代码-r-国家代码-分辨率,比如:drawable-zh-rCN-hdpi 或 drawable-en-rUS-mdpi。使用方式如下:
- 在XML文件中需要使用到图片的地方用表达式: @drawable/icon?
- 代码中使用:R.drawable.icon。Android环境本身就会根据索引找到对应的图片
3.6 layout布局资源(/res/layout目录)
一般在Android项目中定义了Layout资源:
- 在XML文件中可以通过如下语法格式来访问它:@layout/<file_name>
- 在Java代码中则按如下语法格式来访问它:R.layout.<file_name>
3.7 menu布局资源(/res/menu目录)
一般在Android项目中定义了menu资源:
- 在XML文件中可以通过如下语法格式来访问它:@menu/<file_name>
- 在Java代码中则按如下语法格式来访问它:R.menu.<file_name>
3.8 自适应不同屏幕资源
Android应用的特点:屏幕尺寸、分辨率差别非常大,但应用要在所有的设备上都能正常运行。为了适应不同屏幕的资源,最简单做法就是为不同屏幕尺寸、不同屏幕分辨率提供相应的布局文件、Drawable资源。
通常来说,屏幕资源需要考虑如下3个方面:
- 屏幕尺寸:small(小屏幕)、normal(中屏幕)、large(大屏幕)、xlarge(超大屏幕)
- 屏幕分辨率:ldpi(低分辨率)、mdpi(中分辨率)、hdpi(高分辨率)、xhdpi(超高分辨率)
- 屏幕方向:分为land(横屏)和port(竖屏)两种,需要在res目录下建立layout-port和layout-land两个目录,分别放置竖屏和横屏两种布局文件,以适应对横屏竖屏自动切换。
布局资源、Drawable资源目录的自动选取说明如下:
- Android 默认把drawable目录分为4个(drawable-xhdpi | drawable-hdpi | drawable- mdpi |? drawable-ldpi),这四者主要是根据不同的分辨率会选择不同的drawable资源文件。
- 布局文件layout目录(layout-small | layout-normal | layout-large | layout-xlarge),四者主要是根据不同的分辨率会选择不同的layout布局文件。
3.9 关于资源引用的特殊说明
android系统对所有的xml资源文件其实是不加区别的,觉得values资源类型的不在于放在什么什么文件,而在于标签名,比如string-array的标签名决定了这是一个array资源。理解了原理,但最后还是建议将这些资源放在对应的位置上,这也算是Android不成文的规定。
4 使用Drawable资源(/res/drawable)
Drawable资源通常保存在/res/drawable目录,实际上可能保存在/res/drawable-ldpi,/res/drawable-mdpi,/res/drawable-hdpi 目录下。
4.1 图片资源
@1 一般在Android项目中定义了图片资源
- 在XML文件中可以通过如下语法格式来访问它:@drawable/<file_name>
- 在Java代码中则按如下语法格式来访问它:R.drawable.<file_name>
@2 在程序中为了获取实际的Drawable对象,Resources提供了Drawable getDrawable(int ResId)方法获取
注意:Android要求图片资源的文件名必须符合Java的标识符命名规则,否则SDK无法为该图片在R类中生成资源索引
4.2 statelistdrawable资源
4.2.1?StateListDrawable基础
一个StateListDrawable是在xml文件中定义,根据该对象不同的状态,用几张不同的图片来代表相同的图形。StateListDrawable用于组织多个Drawable对象,会随着目标组件状态的改变而自动切换。比如,一个按钮,有多种状态,获取焦点,失去焦点,点击等等。使用StateListDrawable可以根据不同的状态提供不同的图片背景。
注意:在XML文件中描述这些状态列表。在唯一的一个<selector>标签下,使用<item>标签来代表一个图形。每个<item>标签使用各种属性来描述它所代表的状态所需要的drawable资源。状态再次发生改变时,都会从上到下遍历这个状态列表,第一个和它匹配的将会被使用(而不是去选择最适合的匹配)。
语法格式如下所示:
<?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>
4.2.2 属性详细解读
关于StateListDrawable中XML属性,查看官方文档:StateListDrawable XML属性详细解读
4.2.3 使用实例
@1 这里主要是Button使用selector的一个实例,如下所示:
<?xml version="1.0" encoding="UTF-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
? ? <!-- 默认时的背景图片 --> ? ?
? ? <item android:drawable="@drawable/pic1" /> ? ??
? ? <!-- 没有焦点时的背景图片 --> ? ?
? ? <item android:state_window_focused="false" ? ??
? ? ? ? ? android:drawable="@drawable/pic1" /> ? ??
? ? <!-- 非触摸模式下获得焦点并单击时的背景图片 --> ? ?
? ? <item android:state_focused="true" android:state_pressed="true" ? ??
? ? ? ? ? android:drawable= "@drawable/pic2" /> ? ?
? ? <!-- 触摸模式下单击时的背景图片 --> ? ?
? ? <item android:state_focused="false" android:state_pressed="true" ? ??
? ? ? ? ? android:drawable="@drawable/pic3" /> ? ??
? ? <!--选中时的图片背景 ?--> ? ?
? ? <item android:state_selected="true" ? ??
? ? ? ? ? android:drawable="@drawable/pic4" /> ? ??
? ? <!--获得焦点时的图片背景 ?--> ? ?
? ? <item android:state_focused="true" ? ??
? ? ? ? ? android:drawable="@drawable/pic5" /> ?
</selector>
@2 这是一个EditText使用selector的一个实例,如下所示:
<?xml version="1.0" encoding="UTF-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
?? ?<!-- 指定获得焦点时的颜色 -->
?? ?<item android:state_focused="true"
?? ??? ?android:color="#f44"/>
?? ?<!-- 指定失去焦点时的颜色 -->
?? ?<item android:state_focused="false"
?? ??? ?android:color="#eee"/>
</selector>
4.3 Layerdrawable资源
4.3.1?LayerDrawable基础
LayerDrawable是管理一组drawable对象的drawable(本质是图层叠加)。在LayerDrawable的drawable资源按照列表的顺序绘制,列表的最后一个drawable绘制在最上层。可以用于图层的叠加显示,还可以用于SeekBar这类控件重新绘制主题与效果。它所包含的一组drawable资源用多个<item>元素表示,一个<item>元素代表一个drawable资源。
语法格式如下所示:
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@drawable/black_lotus"
android:left="20dp"
android:top="20dp">
</item>
<item android:drawable="@drawable/black_lotus"
android:left="40dp"
android:top="40dp">
</item>
<item android:drawable="@drawable/black_lotus"
android:left="60dp"
android:top="60dp">
</item>
</layer-list>
4.3.2 属性详细解读
关于LayerDrawable中XML属性,查看官方文档:LayerDrawable XML属性详细解读
说明:在默认的情况下,所有的drawable item都会缩放到合适的大小来适应视图。因此,在一个layer-list中定义不同的位置可能会增加视图的尺寸和被自动缩放。为了避免被缩放,可以再<item>节点里加上<bitmap>元素来指定一个drawable,并且定义一些不会被拉伸的gravity属性,例如center。下面在item里面定义一个drawable,图片就会自动缩放以适应视图的大小。
<item android:drawable="@drawable/image" />
为了避免缩放,可以使用<bitmap>的子元素来指定drawable资源
<item><bitmap android:src="@drawable/image" android:gravity="center" /></item>
4.3.3?使用实例
@1 这是SeekBar使用layer-list的一个实例,如下所示:
<?xml version="1.0" encoding="UTF-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
?? ?<!-- 定义轨道的背景 -->
?? ?<item android:id="@android:id/background"
?? ??? ?android:drawable="@color/black" />
?? ?<!-- 定义轨道上已完成部分的外观-->
?? ?<item android:id="@android:id/progress"
?? ??? ?android:drawable="@color/cyan" />
</layer-list> ?
@2 这是图形叠加的使用实例,如下所示:
<?xml version="1.0" encoding="utf-8"?>?
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">?
? ? <item>
? ? ? <bitmap android:src="@drawable/ic_launcher"
? ? ? ? android:gravity="center" />
? ? </item>
? ? <item android:top="25dp" android:left="25dp">
? ? ? <bitmap android:src="@drawable/ic_launcher"
? ? ? ? android:gravity="center" />
? ? </item>
? ? <item android:top="50dp" android:left="50dp">
? ? ? <bitmap android:src="@drawable/ic_launcher"
? ? ? ? android:gravity="center" />
? ? </item>
</layer-list>
4.4 shapedrawable资源
4.4.1 shapedrawable基础
shapeDrawable用于定义一个基本的几何图形(矩形、圆形、线条等),这样做可以减少美工的工作量,而且可以画出更好看的背景图。
语法格式如下所示:
<?xml version="1.0" encoding="utf-8"?>
<shape
xmlns:android="http://schemas.android.com/apk/res/android"
android:shape=["rectangle" | "oval" | "line" | "ring"] >
<corners
android:radius="integer"
android:topLeftRadius="integer"
android:topRightRadius="integer"
android:bottomLeftRadius="integer"
android:bottomRightRadius="integer" />
<gradient
android:angle="integer"
android:centerX="integer"
android:centerY="integer"
android:centerColor="integer"
android:endColor="color"
android:gradientRadius="integer"
android:startColor="color"
android:type=["linear" | "radial" | "sweep"]
android:useLevel=["true" | "false"] />
<padding
android:left="integer"
android:top="integer"
android:right="integer"
android:bottom="integer" />
<size
android:width="integer"
android:height="integer" />
<solid
android:color="color" />
<stroke
android:width="integer"
android:color="color"
android:dashWidth="integer"
android:dashGap="integer" />
</shape>
4.4.2? 属性详细解读
关于ShapeDrawable中XML属性,查看官方文档:ShapeDrawable XML属性详细解读
4.4.3?使用实例
@1 line的使用实例(线)
<?xml version="1.0" encoding="UTF-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
????android:shape="line">
????<stroke
????????android:width="10dp"
????????android:color="#FF0000FF"
????????android:dashWidth="1dp"
????????android:dashGap="1dp" />
</shape>
@2 rectangle的使用实例(圆角矩形)
<?xml version="1.0" encoding="UTF-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"?
????android:shape="rectangle">
????<!-- 定义填充渐变颜色 -->
????<gradient?
????????android:startColor="#FFFF0000"?
????????android:endColor="#80FF00FF"?
????????android:angle="45"/>?
????<!-- 设置内填充 -->
????<padding android:left="7dp"?
????????android:top="7dp"?
????????android:right="7dp"?
????????android:bottom="7dp" />
????<!-- 设置圆角矩形 -->
????<corners android:radius="8dp" />
????<!-- 设置边框 -->
????<stroke android:width="3dip" android:color="#ff0" />
</shape>
@3 oval的使用实例(椭圆)
<?xml version="1.0" encoding="UTF-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"?
????android:shape="oval">
????<!-- 定义填充渐变颜色 -->
????<gradient?
????????android:startColor="#ff0"?
????????android:endColor="#00f"?
????????android:angle="45"
????????android:type="sweep"/>?
????<!-- 设置内填充 -->
????<padding android:left="7dp"?
????????android:top="7dp"?
????????android:right="7dp"?
????????android:bottom="7dp" />
????<!-- 设置圆角 -->
????<corners android:radius="8dp" />?
</shape>
@4 ring的使用实例(环形)
<?xml version="1.0" encoding="UTF-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
????android:shape="ring"
????android:innerRadius="12dp"
????android:innerRadiusRatio="1"
????android:thickness="0dp"
????android:thicknessRatio="4"
????android:useLevel="false"
????>
????<stroke android:width="1dp" ?android:color="#ff0000" />
????<solid ?android:color="#ff0000" ?/>
</shape>
4.5?clipdrawable资源
4.5.1?ClipDrawable基础
ClipDrawable 是对一个Drawable进行剪切操作,可以控制这个drawable的剪切区域,以及相相对于容器的对齐方式,android中的进度条就是使用一个ClipDrawable实现效果的,它根据level的属性值,决定剪切区域的大小。
注意:ClipDrawable是根据level的大小控制图片剪切操作的,官方文档的note中提到:level的大小从0到10000,level为0时完全不显示,为10000时完全显示。是用Drawable提供的setLevel(int level)方法来设置剪切区域。
语法格式如下所示:
<?xml version="1.0" encoding="utf-8"?>
<clip
xmlns:android="http://schemas.android.com/apk/res/android"
android:drawable="@drawable/drawable_resource"
android:clipOrientation=["horizontal" | "vertical"]
android:gravity=["top" | "bottom" | "left" | "right" | "center_vertical" |
"fill_vertical" | "center_horizontal" | "fill_horizontal" |
"center" | "fill" | "clip_vertical" | "clip_horizontal"] />
4.5.2 属性详细解读
关于ClipDrawable中XML属性,查看官方文档:ClipDrawable XML属性详细解读
4.5.3 使用实例
这里使用动态实例(代码+配置的方式)来实现一个特殊效果{使用ClipDrawable对象调用setLevel方法控制截取图片的部分,因此本例设置一个定时器,让程序不断调用ClipDrawable的setLevel方法即可实现图片徐徐展开的效果}
@1 代码如下所示:
public class ClipDrawableTest extends AppCompatActivity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main4);
ImageView imageView = (ImageView) findViewById(R.id.image);
final android.graphics.drawable.ClipDrawable drawable = (android.graphics.drawable.ClipDrawable) imageView.getDrawable();
final Handler handler = new Handler() {
@Override
public void handleMessage(Message msg) {
if (msg.what == 0x1233) {
drawable.setLevel(drawable.getLevel() + 200);
}
}
};
final Timer timer = new Timer();
timer.schedule(new TimerTask() {
@Override
public void run() {
Message msg = new Message();
msg.what = 0x1233;
handler.sendMessage(msg);
if (drawable.getLevel() >= 10000) {
timer.cancel();
}
}
}, 0, 300);
}
}
注意:定义ClipDrawable的用法是把Drawable进行转换的。?
@2 my_clip.xml实现
关键在于android:sec="@drawable/my_clip",调用了这个配置文件。这个配置文件的内容是:
<?xml version="1.0" encoding="UTF-8"?>
<clip xmlns:android="http://schemas.android.com/apk/res/android"
android:drawable="@drawable/test"
android:clipOrientation="horizontal"
android:gravity="center">
</clip>
这里的关键是对齐方式和展示方向,即gravity和clipOrientation来控制展示效果。
@3 main.xml文件的内容
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<ImageView
android:id="@+id/image"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:src="@drawable/my_clip"
/>
</LinearLayout>
?这一个clipDrawable的配置文件完成。调用一个clip配置文件来展示效果。
5 属性资源
5.1 XML属性资源基础
主要针对自定义组件的属性,具体格式如下:?
<?xml version="1.0" encoding="utf-8"?> ?
<resources> ?
? ? <attr name="test" format="string" />?
? ? <declare-styleable name="MyView"> ?
? ? ? ? <attr name="textColor" format="color" /> ? ?
? ? ? ? <attr name="textSize" format="dimension" /> ? ?
? ? ? ? <attr name="text" format="string" /> ?
? ? </declare-styleable> ? ?
</resources> ?
这里定义一个styleable对象,每个styleable对象就是一组attr属性的集合(注意:这里的name属性并不是一定要和自定义类名相同,只是为了好区分对应类的属性而已 )。
attr属性资源的定义:name定义具体的属性名,format表示属性值类型,有以下几种: ?
- reference:参考指定Theme中资源ID,这个类型表示你传的值可以是引用资源。
- string:若希望用类似"@string/test"引用资源的方式,可以写成format="string /reference"
- Color:颜色
- boolean:布尔值 ?
- dimension:尺寸值 ?
- float:浮点型 ?
- integer:整型 ?
- fraction:百分数
- flag:位或运算
- enum:枚举 ,如果你提供的属性只能让别人选择,不能随便传入,就可以写成这样 ?
<attr name="language"> ?
????????<enum name="china" value="1"/> ?
????????<enum name="English" value="2"/> ?
</attr> ?
说明:这个属性资源文件是公共的,但是为了方便管理,一般都是一个自定义View里的属性写成一个declare-styleable集合。属性资源所定义的属性到底可以返回什么作用,取决于自定义组件的代码实现 ??
5.2 配合XML属性资源的实例
写出自定义组件的类文件了,然后将这个类里需要外界传入值的属性定义成一个属性资源文件。 在工程里的../res/values/目录下创建一个attrs.xml文件(文件名并不是只能写成这样,这样写只有一个目的,别人一看就知道这个文件是属性资源文件了),具体写法如下:
@1 attr.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<attr name="test1" format="string" />
<declare-styleable name="MyView">
<attr name="textColor" format="color" />
<attr name="textSize" format="dimension" />
<attr name="text" format="string" />
</declare-styleable>
</resources>
@2?在自定义类里引用attrs文件里定义的属性并为自己的属性设置值,代码实现如下:
public class MyView extends View
{
private Paint mPaint;
private Context mContext;
private static String mString;
private String test;
public MyView(Context context)
{
super(context);
mPaint = new Paint();
}
public MyView(Context context,AttributeSet attrs)
{
super(context,attrs);
mPaint = new Paint();
/*打开资源,取得declare-styleable集合*/
TypedArray typeArray = context.obtainStyledAttributes(attrs,R.styleable.MyView);
/*从集合中取出对应属性值,第二参数是没用配置该属性时所用的默认值*/
int textColor = typeArray.getColor(R.styleable.MyView_textColor,0XFFFFFFFF);
float textSize = typeArray.getDimension(R.styleable.MyView_textSize, 36);
mString = typeArray.getString(R.styleable.MyView_text);
/*设置自己的类成员变量*/
mPaint.setTextSize(textSize);
mPaint.setColor(textColor);
/*关闭资源*/
typeArray.recycle();
}
@Override
protected void onDraw(Canvas canvas)
{
super.onDraw(canvas);
mPaint.setStyle(Style.FILL);
canvas.drawRect(new Rect(10, 10, 90, 90), mPaint);
mPaint.setColor(Color.BLUE);
canvas.drawText(mString, 10, 110, mPaint);
}
}
@3 使用自定义组件,并设置属性
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:myandroid="http://schemas.android.com/apk/res/com.ags.androidtest"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/hello"/>
<cn.com.androidtest.ui.MyView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
myandroid:textColor="#ff0000"
myandroid:textSize="20px"
myandroid:text="myview"/>
</LinearLayout>
注意:
在XML使用该组件时要为该自定义组件设置一个命名空间,命名空间写法为:
<XXX xmlns:空间名="http://schemas.android.com/apk/res/自定义组件所在包名"/>
写包名时你的自定义View所在包类的文件夹下,那么包名只能写成最顶层包[com.ags.androidtest],而不能是[com.ags.androidtest.xxx]。
6 RAW原始资源
android中没有提供专门支持的文件叫原始资源文件。android原始资源一般放在/res/raw目录和/assets/目录下。
6.1 原始文件索引获取
@1 assets目录下的文件
通过AssetMananger来管理,一般用如下方法来访问Assets资源
//根据文件名来获取原始资源对应的输入流
InputStream open(String fileName)
//根据文件名获取原始资源对的AssetFileDescriptor资源描述,应用程序可以通过它来获取原始资源
AssetFileDescriptor openFd(String fileName)
@2 res/raw目录下的文件
Android SDK会处理该目录下的原始资源,会在R清单类中为该目录下资源生成索引项
- 在xml文件中可以通过如下语法格式来访问:@[<package_name>:]raw/file_name
- 在Java文件中按如下语法来访问:R.raw.<file_name>
6.2 使用案例
主要使用两种方式获取资源,实现利用MediaPlayer类来播放声音的功能,代码如下:
public class RawResTest extends AppCompatActivity
{
MediaPlayer mediaPlayer1 = null;
MediaPlayer mediaPlayer2 = null;
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
//方式1:直接根据声音文件的ID来创建MediaPlayer对象1。
mediaPlayer1 = MediaPlayer.create(this, R.raw.bomb);
//方式2:获取该应用的AssetManager
AssetManager am = getAssets();
try
{
//获取指定文件对应的AssetFileDescriptor。
AssetFileDescriptor afd = am.openFd("shot.mp3");
mediaPlayer2 = new MediaPlayer();
//使用MediaPlayer加载指定的声音文件。
mediaPlayer2.setDataSource(afd.getFileDescriptor());
mediaPlayer2.prepare();
}
catch (IOException e)
{
e.printStackTrace();
}
// 获取第一个按钮,并为它绑定事件监听器
Button playRaw = (Button) findViewById(R.id.playRaw);
playRaw.setOnClickListener(new OnClickListener()
{
@Override
public void onClick(View arg0)
{
//播放声音
mediaPlayer1.start();
}
});
// 获取第二个按钮,并为它绑定事件监听器
Button playAsset = (Button) findViewById(R.id.playAsset);
playAsset.setOnClickListener(new OnClickListener()
{
@Override
public void onClick(View arg0)
{
//播放声音
mediaPlayer2.start();
}
});
}
}
7 样式与主题
7.1 样式资源
7.1.1 资源简介
如果经常对某个类型的组件指定大致相似的格式时,每次都为View组件重复指定这些属性,会有大量工作量,不利于项目后期的维护。一个样式等于一组格式的集合,假如某段文本使用某个样式,那么该格式将整体应用于这段文本;Android样式与此类似,也包含一组格式,为一个组件设置使用某个样式时。该样式包含的全部格式将会应用于该组件。
样式是属性的集合,例如定义属性fontColor、fontSize、layout_width、layout_height等,以独立的资源文件存放在XML文件中,并设置样式的名称。
样式资源在res/values/下创建Style XML资源文件,这里创建的Style资源文件名命名为styles.xml,这个可以自己自定义。
7.1.2 style样式资源语法规则
styles.xml的语法格式内容如下:
<?xml version="1.0" encoding="utf-8"?> ?
<resources> ?
? ? <style name="wrap_content"> ?
? ? ? ? <item name="android:layout_width">wrap_content</item> ?
? ? ? ? <item name="android:layout_height">wrap_content</item> ?
? ? </style> ?
</resources>
Android Style(类似Web中CSS设计思路)让设计与内容分离,且可以方便的继承、覆盖。
7.1.3 style的继承方式
style的继承方式有2种:
- 通过style的parent属性。
- 使用类似CSS中的命名规则来实现。
分别解读如下:
@1?通过parent属性,修改styles.xml实现方式如下:
<?xml version="1.0" encoding="utf-8"?> ?
<resources> ?
? ? <style name="wrap_content"> ?
? ? ? ? <item name="android:layout_width">wrap_content</item> ?
? ? ? ? <item name="android:layout_height">wrap_content</item> ?
? ? </style> ?
? ? ??
? ? <style name="inherit" parent="wrap_content"> ?
? ? ? ? <item name="android:textColor">#00FF00</item> ?
? ? </style> ?
</resources>
新增名为inherit的样式,并且继承名为wrap_content样式,即inherit具有wrap_content样式中定义的属性参数。引用方式为:style="@style/inherit"。
@2 通过命名规则实现,xml配置代码如下所示:
<?xml version="1.0" encoding="utf-8"?> ?
<resources> ?
? ? <style name="wrap_content"> ?
? ? ? ? <item name="android:layout_width">wrap_content</item> ?
? ? ? ? <item name="android:layout_height">wrap_content</item> ?
? ? </style> ?
? ? ??
? ? <style name="wrap_content.inherit"> ?
? ? ? ? <item name="android:textColor">#00FF00</item> ?
? ? </style> ?
</resources>
通过“.”号实现继承。引用方式:style="@style/wrap_content.inherit"
7.1.4 样式布局使用案例
样式在布局文件中的使用实例如下所示:
<?xml version="1.0" encoding="utf-8"?> ?
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" ?
? ? android:orientation="vertical" ?
? ? android:layout_width="fill_parent" ?
? ? android:layout_height="fill_parent" ?
? ? > ?
<TextView ?
? ? style="@style/wrap_content" ?
? ? android:textColor="#00FF00" ?
? ? android:text="@string/hello" /> ? ? ? ? ? ?
<TextView ?
? ? style="@style/wrap_content" ?
? ? android:text="@string/hello" /> ? ? ? ?
<Button ??
? ? style="@style/wrap_content" ?
? ? android:text="@string/hello" ?
/> ?
</LinearLayout> ?
最后总结:style就是为控件的UI属性所做的封装,这样方便复用。
7.2?主题资源
7.2.1 基本概念
- 主题资源与样式的区别:主题不能用于单个View组件,它是对整个应用所有Activity或指定Activity起作用。
- 主题格式:改变窗口外观的格式,例如窗口标题、窗口边框等。
7.2.2 配置与使用主题
这里通过一个案例来添加一个新的主题(所有窗口都添加边框、背景的主题)在XML文件中定义主题,配置如下所示:
<?xml version="1.0" encoding="UTF-8"?>
<resources>
?? ?<style name="AgsTheme">
?? ??? ?<item name="android:windowNoTitle">true</item>
?? ??? ?<item name="android:windowFullscreen">true</item>?? ??? ?
?? ??? ?<item name="android:windowFrame">@drawable/window_border</item>
?? ??? ?<item name="android:windowBackground">@drawable/star</item>
?? ?</style>?? ?
</resources>
@1 在AndroidManifest.xml文件中使用主题
在application中android:theme属性中指定特定的主题,配置如下所示:
<?xml version="1.0" encoding="utf-8"?>
<manifest
?? ?xmlns:android="http://schemas.android.com/apk/res/android"
?? ?package="com.ags.res"
?? ?android:versionCode="1"
?? ?android:versionName="1.0">
?? ?<uses-sdk
?? ??? ?android:minSdkVersion="10"
?? ??? ?android:targetSdkVersion="17" />
?? ?<application
?? ??? ?android:icon="@drawable/ic_launcher"
?? ??? ?android:label="@string/app_name"
?? ??? ?android:theme="@style/AgsTheme">?? ??? ?
?? ??? ?<activity
?? ??? ??? ?android:name=".StyleResTest"
?? ??? ??? ?android:label="@string/app_name">
?? ??? ??? ?<intent-filter>
?? ??? ??? ??? ?<action android:name="android.intent.action.MAIN" />
?? ??? ??? ??? ?<category android:name="android.intent.category.LAUNCHER" />
?? ??? ??? ?</intent-filter>
?? ??? ?</activity>
?? ?</application>
</manifest>
说明:Android中提供了几种内置的主题资源,通过查询Android.R.style类可以看到Android已经设计好的主题。主题和样式一样,可以通过集成来实现自定义主题,参考模板如下:
<resources>
<style name="AgsTheme" parent=“@android:style/Theme.Dialog”>
...
</style>
</resources>
@2 在代码中使用主题,方式如下:
public class StyleResTest extends Activity
{
?? ?@Override
?? ?public void onCreate(Bundle savedInstanceState)
?? ?{
?? ??? ?super.onCreate(savedInstanceState);
? ? ? ? setTheme(R.style.CrazyTheme);//注意:
?? ??? ?setContentView(R.layout.main);
?? ?}
}
|