• 属性(Attribute)资源


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

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

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

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

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

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

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

         程序清单 esvaluesattrs.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。

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

       如下图:

     

         

            

        

  • 相关阅读:
    编程谜题:提升你解决问题的训练场
    同态加密实现数据隐私计算,能让你的小秘密更加秘密
    interviewstreet pair
    x & (x 1)==0
    uva 11991 Easy Problem from Rujia Liu?
    hdoj 1230 火星A+B
    hdoj 1711 KMP Number Sequence
    HackerRank网站,为编码程序员们提供一个以编码谜题和现实生活中遇到的编码难题为基础的新兴的社交平台
    ACM博弈知识汇总
    hdoj 1202 水水更健康
  • 原文地址:https://www.cnblogs.com/wolipengbo/p/3439942.html
Copyright © 2020-2023  润新知