属性(Attribute )资源
前面已经介绍过自定义View组件的开发,自定义View组件与Android系统提供的View
组件一样,既可在Java代码中使用,也可在XML界面布局代码中使用。
当在XML布局文件中使用Android系统提供的View组件时,开发者可以指定多个属性,这些属性可以很好的控制view组件的外观行为。如果用户开发自定义的view组件也需要指定属性,就需要属性资源来帮助了。
属性资源文件夹放置在/res/values/目录下,根元素也是<resoures.../>,该元素里包含如下两个子元素。
attr子元素: 定义一个属性。
declare-styleable子元素: 定义一个styleable对象,每个styleable对象就是一组attr属性的集合。
当我们使用属性文件定义了属性之后,接下来就可以在自定义组件的构造器中通过AttributeSet 对象来获取这些属性了。
例如我们想开发一个默认带动画效果的图片,该图片显示时,自动从全透明变到完全不透明,为此我们需要开发一个自定义组件,但这个自定义组件需要指定一个额外duration 属性,该属性控制动画的持续时间。
为了在自定义组件中使用duration属性,需要先定义如下属性资源文件。
attr.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!-- 定义一个属性 -->
<attr name="duration"></attr>
<!-- 定一个styleable -->
<declare-styleable name="AlphaImageView"
>
<attr name="duration"/>
</declare-styleable>
</resources>
上面的资源属性起什么作用取决于自定义组件的代码实现 。
注意 : 在属性资源中定义 <declare-styleable.../>元素时,也可以在其内部直接<attr.../>定义属性,使用<attr.../>指定一个format属性值即可。如上面我们可以指定<attr name="duration" format="integer"/> .
程序清单: \src\com\example\attributetest\AlphaImageView.java
package com.example.attributetest;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.os.Handler;
import android.os.Message;
import android.util.AttributeSet;
import android.widget.ImageView;
import java.util.Timer;
import java.util.TimerTask;
public class AlphaImageView extends ImageView {
//图像透明度每次改变大小
private int alphaDelta = 0;
//记录图片当前透明度
private int curAlpha = 0;
//每隔多少毫秒透明度改变一次
private final int SPEED = 300;
Handler handler = new Handler(){
public void handleMessage(android.os.Message msg) {
if(msg.what == 0x123){
//每次增加curAlpha的值
curAlpha += alphaDelta;
if(curAlpha > 255){
curAlpha = 255;
}
//修改Imageview的透明度
AlphaImageView.this.setAlpha(curAlpha);
}
};
};
public AlphaImageView(Context context, AttributeSet attrs) {
super(context, attrs);
TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.AlphaImageView);
//获取duration参数
int duration = typedArray.getInt(R.styleable.AlphaImageView_duration, 0);
//计算图像透明度每次修改的大小
alphaDelta = 255 * SPEED/duration;
}
@Override
protected void onDraw(Canvas canvas) {
// TODO Auto-generated method stub
this.setAlpha(curAlpha);
super.onDraw(canvas);
final Timer timer = new Timer();
timer.schedule(new TimerTask() {
@Override
public void run() {
// TODO Auto-generated method stub
Message msg = new Message();
msg.what = 0x123;
if (curAlpha > 255) {
timer.cancel();
}else {
handler.sendMessage(msg);
}
}
}, 1000, SPEED);
}
}
activity_main.xml布局文件
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:wlh="http://schemas.android.com/apk/res/com.example.attributetest"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="com.example.attributetest.MainActivity" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/hello_world" />
<com.example.attributetest.AlphaImageView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:src="@drawable/wallpaper_01"
wlh:duration="6000"
/>
</RelativeLayout>
其中R.styleable.AlphaImageView_duration,R.styleable.AlphaImageView,是android sdk根据资源自动生成。
布局中定义了duration的属性,注意该属性位于http://schemas.android.com/apk/res/com.example.attributetest 即是 http://schemas.android.com/apk/res/ + “项目子包”
主程序什么都不用修改,主程序只要简单负责加载、并显示上面界面布局文件,运行改程序即可看到该图片从无到有,慢慢显示出来的效果。
其实这种属性值也可以通过别的方式来存储或配置,例如 settingsdb的值。