自定义属性

安卓的资源文件非常丰富,每个系统组件都包含了各种属性。当然,当用户想自定义一个特定的组件时,用户会想

:可不可以定义一些特定的属性,这些属性不再是以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>

代码非常简单,上传了!

posted on 2014-05-03 16:35  silentsea  阅读(278)  评论(0编辑  收藏  举报

导航