自定义属性
安卓的资源文件非常丰富,每个系统组件都包含了各种属性。当然,当用户想自定义一个特定的组件时,用户会想
:可不可以定义一些特定的属性,这些属性不再是以android:开头,而是 test:属性 呢?答案是肯定的。为了
使安卓应用组件更加灵活多样,安卓开发包提供了用户自己定义属性的功能。下面我详细说下自定义属性的一些知
识。 首先在/res/values目录下创建一个attr.xml文件。属性资源文件的根元素是<resources.../>,该元素中包含两个
子元素:<attr.../>:定义一个属性;<declare-styleable/>:定义一个styleable对象。每个styleable对象是一
组attr属性的组合。 例如,我们定义如下属性:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<attr name="animation"/>
<declare-styleable name="AnimImageView">
<attr name="animation">
</attr>
</declare-styleable>
</resources>
此时,保存一下,Android SDK会根据属性资源文件在R.java文件中自动生成一个attr类和一个styleable类。attr
类包含一个animation成员变量,它的值是animation属性的地址。styleable类包含一个AnimImageView的整型数组
,它包含AnimImageView中所包含的属性的入口地址,和其中属性的地址偏移量。如下:
public static final class attr {
public static final int animation=0x7f010000;
}
public static final class styleable {
public static final int[] AnimImageView = { 0x7f010000 };
public static final int AnimImageView_animation = 0;
}
这里可以看出,上述代码中R.attr.animation的值和R.AnimImageView[AnimImageView_animation]的值是一样的。
(其中,public static final int AnimImageView_animation = 0指的是数组地址的偏移量。)也就是说同一属
性的入口地址一样。所以不管什么View组件,只要定义了这个自定义属性test:animation,它的入口都只有一个,
值也只有一个。 假如我们再定义一个:
<declare-styleable name="OtherView">
<attr name="animation"/>
<attr name="duration"/>
</declare-styleable>
R.styleable.OtherView[OtherView_animation]的值也是一样的,而R.styleable.OtherView[OtherView_duration]的地址却不一样。 R.java的代码如下: public static final class attr {
public static final int animation=0x7f010000;
public static final int duration=0x7f010001;
}
自动生成了attr.duration.
public static final class styleable {
public static final int[] AnimImageView = {
0x7f010000
};
public static final int AnimImageView_animation = 0;
public static final int[] OtherView = {
0x7f010000, 0x7f010001
};
public static final int OtherView_animation = 0;
public static final int OtherView_duration = 1;
};
}
OtherView中有两个入口地址的值,分别是animation,和duration。偏移量分别是 public static final int
OtherView_animation = 0;
public static final int OtherView_duration = 1。
以上讲解了如何定义自定义属性。接下来我们应用下自定义的属性。 在.java中自定义一个AnimImageView,代码如下:
package com.example.test16;
import android.content.Context;
import android.content.res.TypedArray;
import android.util.AttributeSet;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.ImageView;
public class BnimImageView extends ImageView{
Animation anim;
int animId;
public AnimImageView(Context context, AttributeSet attrs) {
super(context, attrs);
// TODO Auto-generated constructor stub
TypedArray typedArray=context.obtainStyledAttributes(attrs, R.styleable.AnimImageView);
animId=typedArray.getResourceId(R.styleable.AnimImageView_animation, android.R.anim.fade_in);
anim=(Animation)AnimationUtils.loadAnimation(context, animId); startAnimation(anim);
}
}
其中重要的是红色标出部分。用TypeArray引入AnimImageView的属性组。实际就是将AnimImageView中的所有属性
存入一个TypeArray中用 animId=typedArray.getResourceId(R.styleable.AnimImageView_animation,
android.R.anim.fade_in);方法获取动画资源的ID地址,其中android.R.anim.fade_in指如果未定义animation属
性默认的动画效果。 当然如上所述,R.styleable.AnimImageView_animation的值和OtherView_animation的值是一样的。完全可以用
TypedArray typedArray=context.obtainStyledAttributes(attrs, R.styleable.OtherView)来代替。但是这样不
利于程序可读性。
接下来就可以在layout中添加自定义组件并设置自定义属性了。
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:test16="http://schemas.android.com/apk/res/com.example.test16"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:gravity="center"
tools:context=".MainActivity" >
<com.example.test16.AnimImageView android:id="@+id/iv"
android:layout_width="120dp"
android:layout_height="match_parent"
android:src="@drawable/back2"
test16:animation="@anim/anim"
/>
</LinearLayout>
在AnimImageView中指定一个animation属性,注意该属性位于"http://schemas.android.com/apk/res/+项目子包
名"命名空间下,例如本应用的子包名为com.example.test16,那么animation属性就位
于"http://schemas.android.com/apk/res/com.example.test16 "下。第一行红体子代码用于导入"http://schemas.android.com/apk/res/com.example.test16"命名空间,并制定
对应短名为test16,然后就可以自己创建动画资源添加属性。 我做的动画为:
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<alpha android:fromAlpha="0"
android:toAlpha="255"
android:interpolator="@android:anim/linear_interpolator"
android:duration="2000"
android:fillAfter="true"
/>
<translate android:fromXDelta="-120"
android:toXDelta="0"
android:interpolator="@android:anim/linear_interpolator"
android:duration="2000"
android:fillAfter="true"
/>
</set>
代码非常简单,上传了!