AndroidUI控件的自定义属性

来源:互联网 发布:上帝已死 知乎 编辑:程序博客网 时间:2024/05/17 23:45

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

一. 基本原理:
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();
原创粉丝点击