自定义View之添加自定义属性

来源:互联网 发布:safari 64位 windows 编辑:程序博客网 时间:2024/05/21 08:57

前言

android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"

在layout文件中进行布局时,常常会通过像上面这样的语句来为view添加属性。这样的方式可以大大简化布局工作,并且复用性强。本文将详细讲解如何为自己的view添加自定义属性,以及这些属性是如何发挥作用的。

编写attr.xml文件

在res/values/目录下创建attrs.xml文件,在resource根标签下添加declare-styleable标签,之后就可以开始编辑自定义属性了。下面为一个示例:

<?xml version="1.0" encoding="utf-8"?><resources>    <declare-styleable name="MyViewAttr">        <attr name="name" format="string"/>        <attr name="color" format="color"/>        <attr name="hasBackground" format="boolean"/>        <attr name="background" format="reference"/>        <attr name="size" format="dimension"/>        <attr name="gravity">            <flag name="top" value="0"/>            <flag name="center" value="1"/>            <flag name="bottom" value="2"/>        </attr>    </declare-styleable></resources>

首先,紧跟在declare-styleable后面的name是这个自定义属性集的名字,之后在代码中引用属性时会用到。每个属性用一个attr标签来声明,标签内的name为这个属性的名字,format为这个属性的数据格式,有以下几种:

  • reference:引用其他资源。例:@drawable/bg;
  • color:颜色。例:#FF0000;
  • boolean:布尔值。例:false;
  • dimension:尺寸值。例:100dp;
  • float:浮点数。例:0.7f;
  • integer:整数。例:100;
  • string:字符串。例:hello world;
  • fraction:百分数。例:50%
  • enum:枚举值。例:<enum name=”horizontal” value=”0”>;
  • flag:位。例:<flag name=”top” value=”0”/>

下面补充几点:
(1)可以将两种或多种format用|连接起来,表示都可使用。例:reference|color。
(2)为属性提供几种可选值的方法:

<attr name="gravity">    <flag name="top" value="0"/>    <flag name="center" value="1"/>    <flag name="bottom" value="2"/></attr>

(3)可以在resources标签下声明多个declare-styleable,但它们不能有相同名称的属性。

在layout文件中使用自定义属性

属性集编写完毕后,就可以在layout文件中引用它的内容了。为了和系统空间区分开,需要引入自己的namespace。Android Studio中只需在根布局中加上这么一行:

xmlns:custom = "http://schemas.android.com/apk/res-auto"

xmlns:后面的就是引入的namespace的名字,这里取名为custom。之后就可以通过它来引用自定义属性了。示例如下:

android:layout_width="match_parent"android:layout_height="match_parent"custom:name="myView"custom:color="#FF0000"custom:hasBackground="true"custom:background="@drawable/bg"custom:size="100dp"custom:gravity="bottom"

获取自定义属性

到这里为止,自定义属性还不能发挥作用。接下来需要在自定义的view的构造器中获取它们。示例如下:

public MyView(Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {    super(context, attrs, defStyleAttr, defStyleRes);    //获取属性集    TypedArray ta = context.obtainStyledAttributes(attrs,R.styleable.MyViewAttr);    try {        //获取各个属性        String name = ta.getString(R.styleable.MyViewAttr_name);        int color = ta.getColor(R.styleable.MyViewAttr_color,Color.RED);        boolean hasBackground = ta.getBoolean(R.styleable.MyViewAttr_hasBackground,false);        Drawable background = ta.getDrawable(R.styleable.MyViewAttr_background);        int gravity = ta.getInt(R.styleable.MyViewAttr_gravity,-1);    }finally {        //回收TypedValue对象        ta.recycle();    }}

总结一下就是这么几步:
(1)调用context.obtainStyledAttributes(attrs,R.styleable.MyViewAttr)获取TypedValue。第一个参数是构造器中的AttributeSet对象,第二个参数为通过<declare-styleable name=”MyViewAttr”>定义的属性集的名称;
(2)调用TypedValue的各种getXXX()方法获取相应的属性。部分方法需要提供默认值;
(3)属性获取完毕后,调用TypedValue的recycle()方法将其回收。

使用自定义属性

最后就是根据获取到的这些值,对view的各个属性进行设置。这个没有固定的方法,需要根据实际情况而定。

原创粉丝点击