在android中,我们经常会在java代码中,或者在xml界面布局代码中使用我们的自定义控件。开发者可以通过自定义自己的控件时继承Android系统提供的view组件,就可以像在使用Android系统提供的view组件时一样,用一些系统中控件的属性来很好地控制View组件中的外观行为。但其实,我们也可以通过自定义自己的控件的属性值,来扩展自定义的属性,继而获得更好的外观控件或者其他的功能。
比如,我们可以通过在应用中添加一个组件属性
duration来达到控制图片从不透明到透明的效果。接下来就让我们来看看效果吧。
第一步,我们可以在/res/values目录下属性资源文件attrs.xml,属性资源文件的根元素也是 < resources…/>元素,该元素有两个子元素
attr:定义一个属性
declare-styleable:定义一个styleable对象,每个styleable对象就 是一组attr属性的集合。
现在就定义了一个名字叫MyImageView的属性组,里面含有一个叫duration的属性。而属性有什么效果,则就看自定义的控件里面是怎么使用它的了。
而上面也有一个等价的写法,就是
- <declare-styleable name="MyImageView">
- <attr name="duration" format="integer"/>
- </declare-tyleable>
接下来就是定义自己的控件 MyImageView
- public class MyImageView extends ImageView {
- //图片透明度每次改变的大小
- private int alphaDelta = 0;
- //记录图片当前的透明度
- private int curAlpha = 0;
- //每隔多少毫秒透明度改变一次
- private final int SPEED = 300;
-
- public MyImageView(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) {
- this.setImageAlpha(curAlpha);
- this.setImageAlpha(curAlpha);
- super.onDraw(canvas);
- 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);
- }
-
- Handler handler = new Handler() {
- @Override
- public void handleMessage(Message message) {
- if (message.what == 0x123) {
- //每次增加curAlpha的值
- curAlpha += alphaDelta;
- if (curAlpha > 255) {
- curAlpha = 255;
- }
- MyImageView.this.setAlpha(curAlpha);
- }
- }
- };
- }
最后,我们就在main_activity.xml文件中引用我们自己定义的控件与属性了。
- <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:mydef="http://schemas.android.com/apk/res/自己的包名"
- xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
- android:layout_height="match_parent" android:paddingLeft="@dimen/activity_horizontal_margin"
- android:paddingRight="@dimen/activity_horizontal_margin"
- android:paddingTop="@dimen/activity_vertical_margin"
- android:paddingBottom="@dimen/activity_vertical_margin" tools:context=".MainActivity">
-
- <com.自己的包名.MyImageView
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:src="@mipmap/ic_launcher"
- mydef:duration="30000"
- />
- </RelativeLayout>
在android studio中,由于应用是采用gradle来构造的,所以也可以直接用这个来替代上面的,AS会自己寻找相应的适合的路径的。 xmlns:mydef=”http://schemas.android.com.apk/res-auto” 包名就是你是你代码放的路径,举例说明 如 com.example.jinhom.attrdef