26
2017
09

AndroidUI控件的自定义属性

一直对自定义属性停留在知道概念,但每次用都要上网搜索,并且不太明白自定义属性的原理,基于最近的一个自定义控件进行了一下总结,方便日后不用再在需要使用的时候再去谷歌。而且弄清楚了自定义属性的基本原理。

一. 基本原理:
1. 每一个UI控件在layout的xml布局中定义,然后在Activity的onCreat方法中通过调用setContentView(R.layout.XX)进行加载调用。(好像是运用反射实例化加载的)
2. 或者通过LayoutInflater.from(this).inflate(R.layout.XX, null);把一个布局文件转换成一个View
底层的示例化方法还需要研究(给自己定为下一个课题吧)

二. 自定义属性的步骤
1. 根据需要在values文件夹下的attrs文件中定义一个属性集合 declare-styleable ,此处模拟定义属性 name、age、 head.

 <!--定义一个属性集合-->
     <declare-styleable name="MyAttrsView">
         <!--定义一个叫name的属性-->
         <attr name="name" format="string"/>
         <attr name="age" format="integer"/>
         <attr name="head" format="reference|color"/>
     </declare-styleable>
  1. 自定义一个View或者ViewGroup ,此处为了记录 定义一个MyAttrsView 继承自View
public class MyAttrsView extends View {
    public MyAttrsView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        }
  1. 在layout的xml中引用这个类
    其中添加了如下三个属性,属性前的chris自由定义 name , age ,head需要包含在attrs文件定义的属性name之中
    chris:age = “27”
    chris:name = “ChrisYu”
    chris:head = “@drawable/devices_icon”
    然后会提示添加自定义属性的命名空间,命名空间有点类似于引用路劲的意思
    xmlns:chris=”http://schemas.android.com/apk/res-auto”
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:chris="http://schemas.android.com/apk/res-auto"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <com.koti.www.myuidemo.myattrs.MyAttrsView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        chris:age = "27"
        chris:name = "ChrisYu"
        chris:head = "@drawable/devices_icon"
        />
</LinearLayout>
  1. 然后载回到自定义的MyAttrsView中,获取自定义的属性并进行相应的操作:
    一般用的最多的是第三种方法,
//获取属性的三种方式
        //1. 利用命名控件获取
       String name = attrs.getAttributeValue("http://schemas.android.com/apk/res-auto" ,"name");
       String age = attrs.getAttributeValue("http://schemas.android.com/apk/res-auto" ,"age");
       String head = attrs.getAttributeValue("http://schemas.android.com/apk/res-auto" ,"head");
       Log.e(TAG, "MyAttrsView: name = " + name + " age = " +age + " head = " + head);

        //2. 通过遍历属性的方式
        for (int i = 0; i < attrs.getAttributeCount() ; i++) {
            Log.i(TAG, attrs.getAttributeName(i) + "====" + attrs.getAttributeValue(i));
        }

        //3. 使用系统工具获取属性
        TypedArray  typedArray = context.obtainStyledAttributes(attrs, R.styleable.MyAttrsView);
        for (int i = 0; i < typedArray.getIndexCount() ; i++){
            int index = typedArray.getIndex(i);
            switch (index){
                case R.styleable.MyAttrsView_name:
                    name1 = typedArray.getString(index);
                    break;
                case R.styleable.MyAttrsView_age:
                    age1 = typedArray.getInt(index,0);
                    break;
                case R.styleable.MyAttrsView_head:
                    Drawable head1 = typedArray.getDrawable(index);
                    BitmapDrawable drawableBit = (BitmapDrawable) head1;
                    headb = drawableBit.getBitmap();
                    break;
            }
        }
        typedArray.recycle();

        //和上面一样,只是没有使用遍历的方式得到属性。
        TypedArray a = context.obtainStyledAttributes(attrs,  R.styleable.MyAttrsView, defStyle, 0);
        name1 = a.getString(R.styleable.MyAttrsView_name);
        age1=  a.getInt(R.styleable.MyAttrsView_age , 0);
        Drawable head1 = a.getDrawable(R.styleable.MyAttrsView_head);
        a.recycle();
上一篇:Android Native内存泄漏诊断 下一篇:Photon_创建工程添加MySql.data库_001