在实际生产实践过程中,我们经常需要自定义组件以供我们使用,在定义这些组件的时候我们也需要定义一些属性供我们在xml文件中使用,如何定义这些属性呢,这就是下面要描述的。
属性资源文件也定义在res/values目录下,属性资源文件的根元素是<resources/>,该元素包含如下两个子元素:
attr子元素:定义一个属性。
declare-stylebale子元素:定义一个styleable对象,每个styleable对象就是一组attr属性的集合。
定义了这些属性之后就可以在自定义组件的构造方法中,通过attributeSet对象获取这些属性。
定义style.xml可以先声明<attr>,也可以在<declare-styleable>属性中一起声明
<resources>
<declare-styleable>
<attr name="size" format="integer"/>
</declare-styleable>
</resources>
note:属性文件定义了之后,该归哪个View去调用,实现怎么样的效果都是具体的View去实现。
下面实现一个渐变alpha的demo显示一下:
attr.xml:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<attr name="duration" />
<declare-styleable name="alphaImageView">
<attr name="duration" />
</declare-styleable>
</resources>
自定义MyImageView.java:
package com.example.android_attribute;
import java.util.Timer;
import java.util.TimerTask;
import android.annotation.SuppressLint;
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;
public class MyImageView extends ImageView {
int alphaDelata = 0;
int curAlpha = 0;
int speed = 300;
@SuppressLint("HandlerLeak")
final Handler myHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
if (msg.what == 0x123) {
curAlpha =curAlpha % 255 + alphaDelata;
//设置alpha,同时触发重绘
MyImageView.this.setAlpha(curAlpha);
}
}
};
public MyImageView(Context context) {
super(context);
}
public MyImageView(Context context, AttributeSet attrs) {
super(context, attrs);
TypedArray typedArray = context.obtainStyledAttributes(attrs,
R.styleable.alphaImageView);
int duration = typedArray
.getInt(R.styleable.alphaImageView_duration, 0);
alphaDelata = 255 * speed / duration;
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
final Timer timer = new Timer();
final TimerTask task = new TimerTask() {
@Override
public void run() {
Message msg = new Message();
msg.what = 0x123;
myHandler.sendMessage(msg);
}
};
System.out.println("------------ondraw");
//调用schedule(task,delay)就可以了,设置setAlpha()的时候会重绘view
timer.schedule(task, 10);
}
}
布局文件activity_main.xml:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
<!--设置自定义属性的命名空间,http://schemas.android.com/apk/res/+自定义组件的包名-->
xmlns:wxapp="http://schemas.android.com/apk/res/com.example.android_attribute"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity" >
<com.example.android_attribute.MyImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:src="@drawable/dog"
<!--使用自定义属性-->
wxapp:duration="60000"/>
</RelativeLayout>
主函数Main.java:
package com.example.android_attribute;
import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
}
实现效果: