当在XML布局文件在使用系统提供的View组件时,开发者可以指定多个属性,这些属性可以很好地控制View组件的外观行为,当开发者自定义组件时,同样需要指定属性,这时就需要属性资源的帮助了。
属性资源文件放在/res/values目录下,根元素也是<resources>,该元素里包含如下两个子元素。
attr子元素:定义一个属性
declare-styleable子元素:定义一个styleable对象,每个styleable对象就是一组attr属性的集合。
在属性资源中定义<declare-styleable.../>元素时,也可在其内部直接使用<attr.../>定义属性,使用<attr.../>时指定一个format属性即可,例如上面我们可以指定<attr name="duration" format="integer"/>
当我们使用属性文件定义了属性之后,接下来就可以在自定义组件的构造器中通过AttributeSet对象来获取这些属性了。
本文中开发一个默认带动画的图片,该图片显示时,自动从全透明变到完全不透明,代码如下:
Activity:
package com.lovo.activity; import android.app.Activity; import android.os.Bundle; public class TestAttrActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); } }
自定义的组件类:
package com.lovo.res; import java.util.Timer; import java.util.TimerTask; 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 com.lovo.activity.R; public class AlphaImageView extends ImageView { // 图像透明度每次改变的大小 private int alphaChangeNumber = 0; // 记录图片当前的透明度 private int curAlpha = 0; // 每隔好多毫秒透明度改变一次 private final int SPEED = 300; Handler handler = new Handler() { public void handleMessage(Message msg) { if (msg.what == 0x123) { // 每次增加curAlpha的值 curAlpha += alphaChangeNumber; 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); // 计算图像透明度每次改变的大小 alphaChangeNumber = 255 * SPEED / duration; } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); this.setAlpha(curAlpha); final Timer timer = new Timer(); // 按固定间隔发送消息,通知系统改变图片的透明度 timer.schedule(new TimerTask() { @Override public void run() { Message msg = new Message(); msg.what = 0x123; if (curAlpha >= 255) { timer.cancel(); } else { handler.sendMessage(msg); } } }, 0, SPEED); } }
布局XML:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:crazyit="http://schemas.android.com/apk/res/com.lovo.activity" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <!-- 使用自定义组件,并指定属性资源中定义的属性 --> <com.lovo.res.AlphaImageView android:layout_width="match_parent" android:layout_height="wrap_content" android:src="@drawable/image5" crazyit:duration="60000" /> </LinearLayout>
属性资源(attr.xml):
<?xml version="1.0" encoding="utf-8"?> <resources> <!-- 定义一个属性 --> <attr name="duration" /> <!-- 定义一个styleable对象来组合多个属性 --> <declare-styleable name="AlphaImageView"> <attr name="duration" /> </declare-styleable> </resources>