属性(Attribute)资源

     前面已经介绍过自定义View组件的开发,自定义View组件与Android系统提供的View组件一样,即可在Java代码中使用,也可在XML界面布局代码中使用。

     当在XML布局文件中使用Android系统提供的View组件时,开发者可以指定多个属性,这些熟悉可以很好地控制View组价的外观行为。如果用户开发的自定义View组件也需要指定属性,就需要属性资源的帮助了。

     属性资源文件也放在/res/values目录下,属性资源的根元素也是<resources.../>,该元素里包含如下两个子元素。

  • attr子元素:定义一个属性。
  • declare-styleable子元素:定义一个styleable对象,每个styleable对象就是一组attr属性的集合。

    当我们使用属性文件定义了属性之后,接下来就可以在自定义组价的构造器中通过AttributeSet对象获取这些属性了。

    例如我们想开发一个默认带动画效果的图片,该图片显示时,自动从透明变成完全不透明,为此我们需要定义一个自定义组件,但这个自定义组件需要指定一个额外duration属性,该属性控制动画的持续时间。

     为了在自定义组件中使用duration属性,需要先定义如下属性资源文件。

     程序清单\res\values\attrs.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
<!-- 定义一个属性 -->
<attr name="duration"  format="integer"></attr>
<!-- 定义一个styleable对象来组合多个属性 -->
<declare-styleable name="AlphaImageView">
    <attr name="duration"/>
</declare-styleable>    
</resources>

上面的属性资源文件定义了该属性之后,至于到底在哪个View组件中使用该属性,该属性到底能发挥什么作用,就不归属性资源文件管了。属性资源所定义的属性到底可以发挥什么作用,取决于自定义组件的代码实现。

       例如如下自定义的AlphaImageView,它获取了定义该组件所指定的duration属性之后,根据该属性来控制图片透明度的改变。程序代码如下。

       提示:

      在属性资源中定义<declare-styeable.../>元素时,也可在其内部直接使用<attr.../>定义属性,使用<attr.../>时指定一个format属性即可,例如上面我们可以指定<attr name="duration"  format="integer"/>

        该程序的后台代码如下:

package com.example.studyresources;

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;

public class AlphaImageView extends ImageView {
   //图像透明度每次改变的大小
    private int alphaDelta=0;
    //记录图片当前的透明度
    private int curAlpha=0;
    //每隔多少毫秒透明度改变一次
    private final int SPEED=300;
    Handler handler=new Handler()
    {

        @Override
        public void handleMessage(Message msg) {
            // TODO Auto-generated method stub
            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);
        // TODO Auto-generated constructor stub
        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);
                }
            }}, 0,SPEED);
    }

}

上面的程序中粗体字代码用于获取定义AlphaImageView时指定的duration属性,并根据该属性计算图片的透明度和变化幅度,接着程序重写了ImageView的onDraw(Canvas canvas)方法,该方法启动了一个任务调度来控制图片透明度的改变。

     上面粗体字代码中的R.styeable.AlphaImageView、R.styeable.AlphaImageView_duration都是Android SDK根据属性资源文件自动生成的。

     接着在界面布局文件使用AlphaImageView时可以为它指定一个duration属性,注意该属性位于"http://schemas.android.com/apk/res/+项目子包"命名空间下,例如本应用的包名为com.example.studyresources,那么duration属性就位于"http://schemas.android.com/apk/res/com.example.studyresources"命名空间下。

     下面是该应用的界面布局文件的代码。

     

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
   xmlns:studyresources="http://schemas.android.com/apk/res/com.example.studyresources"
   android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
  >
<!-- 定义自定义组件,并指定属性资源中定义的属性 -->
 <com.example.studyresources.AlphaImageView
     android:layout_width="fill_parent"
     android:layout_height="wrap_content"
     android:src="@drawable/ee"
     studyresources:duration="60000"
     />

</LinearLayout>

  上面的程序中第一行粗体字代码用于导入http://schemas.android.com/apk/res/com.example.studyresources命名空间,并指定该命名空间对应的短名前缀为studyresources;
   程序第二行粗体字代码用于为AlphaImageView组件指定自定义属性duration的属性值为60000。

    主程序无须指定任何特殊的控制,只要简单地加载并显示上面的界面布局文件,运行该程序时即可看到该图片从无到有,慢慢显示出来的效果。

   如下图:

 

     

        

    

posted @ 2013-11-24 13:32  TealerProg  Views(475)  Comments(0Edit  收藏  举报