Android自定义View之自定义属性

在Android开发中经常会用到自定义View的情况,而在自定义View时,自定义属性是必须用到的。

1、新建一个自定义View如CustomView

它的自定义属性主要是通过declare-styleable标签为其配置自定义属性。具体做法是:在res/values/目录下增加一个resources xml文件,示例如下(res/values/attrs.xml)(属性值如字体、颜色、大小等需要传递到代码中获取并使用

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <declare-styleable name="CustomView">
        <attr name="textString" format="string"/>
        <attr name="colorValue" format="color"/>
        <attr name="textSize" format="dimension"/>
    </declare-styleable>
</resources>

在attrs.xml文件中,外层引入了如下标签:

<declare-styleable name="CustomView">

解释:

所有resources文件中声明的属性都会在R.attr类中生成对应的成员变量:

public final class R{
    public static final class attr{
        public static final int textString=0x7f010038;
        public static final int colorValue=0x7f010039;
        public static final int textSize=0x7f010040;
    }
}

但是声明在标签中的属性,系统还会在R.styleable类中生成相关的成员变量

public static final class styleable{
    public static final int[] CustomView={
        0x7f010038,0x7f010039,0x7f010040
    };
    public static final int CustomView_textString=0;
    public static final int CustomView_colorValue=1;
    public static final int CustomView_textSize=2;
}

可以看出R.styleable.CustomView是一个数组,其中的元素值恰好就是R.attr.textString~textSize的值。而下面的CustomView_textString~CustomView_textSize正好就是其对应的索引

2、编写布局文件,引用自定义的View

<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:background="@color/BgColor"
        

    <com.example.CustomView
        android:id="@+id/customView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:colorValue="@color/textRed"
        app:textString="This is the Custom View!!"
        app:textSize="21sp"
        />

</LinearLayout>

注意:

新增布局文件的命名空间

因为我们自定义了View,并且自定义了属性,而这些属性不再属于

http://schema.adnroid.com/apk/res/android

这个命名空间属于:

http://schema.android.com/apk/res/[你的项目包名]

所以需要在增加的布局文件中的命名空间改成:

http://schema.adnroid.com/apk/res/com.example

关于自定义View的代码,会在下一篇文章中介绍,这里主要是介绍自定义属性的细节

format的定义及应用示例:

1、reference:资源引用

属性定义:

<attr name="background" format="reference"/>

使用示例:

<com.example.CustomView
    android:layout_width="24dp"
    android:layout_height="24dp"
    app:background="@mipmap/bg"
/>

2、color:颜色值

属性定义:

<attr name="textColor" format="color"/>

使用示例:

<com.example.CustomView
    android:layout_width="24dp"
    android:layout_height="24dp"
    app:textColor="#000000"
 />

3、boolean:布尔值

属性定义:

<attr name="focusable" format="boolean"/>

使用示例:

<com.example.CustomView
    android:layout_width="24dp"
    android:layout_height="24dp"
    app:foucusable="true"
/>

4、dimension:尺寸值

属性定义:

<attr name="custonWidth" format="demension"/>

属性使用:

<com.example.CustomView
    app:customWidth="24dp"
    android:layout_height="wrap_content"
/>

5、float:浮点值

属性定义:

<attr name="fromAlpha" format="float"/>

属性使用:

<com.example.CustomView
    android:layout_width
    android:layout_height
    app:fromAlpha="0.5"
/>

6、integer:整型值

属性定义:

<attr name="frameDuration" format="integer"/>

属性使用:

<com.example.CustomView
    app:frameDuration="12"
/>

7、string:字符串

属性定义:

<attr name="textString" format="string"/>

属性使用:

<com.example.CustomView
    app:textString="hello world!!"
/>

8、fraction:百分数

属性定义:

<attr name="pivotX" format="fraction"/>

属性使用:

<com.example.CustomView
    app:pivotX="30%"
/>

9、枚举值

属性定义:

<attr name="orientation">
    <enum name="horizontal" value="0"/>
    <enum name="vertical" value="1"/>
</attr>

属性使用:

<com.example.CustomView
    app:orientation="vertical"
/>

10、flag:位或运算符

属性定义:

<declare-styleable name="CustomView">
     <attr name="windowSoftInputMode">
           <flag name = "stateUnspecified" value = "0" />
           <flag name = "stateUnchanged" value = "1" />
           <flag name = "stateHidden" value = "2" />
           <flag name = "stateAlwaysHidden" value = "3" />
           <flag name = "stateVisible" value = "4" />
           <flag name = "stateAlwaysVisible" value = "5" />
           <flag name = "adjustUnspecified" value = "0x00" />
           <flag name = "adjustResize" value = "0x10" />
           <flag name = "adjustPan" value = "0x20" />
           <flag name = "adjustNothing" value = "0x30" />
     </attr>         
</declare-styleable>

属性使用:

<com.example.CustomView
    app:windowSoftInputMode="stateUnspecified|stateUnchanged|stateHidden"
/>

补充:

(2018-12-12)

在代码构造器中引用时需要注意TypedArrayAttributeSet这两个点,例如:

public CustomView(Context context){
    this(context,null);
}

public CustomView(Context context,AttributeSet attrs){
    this(context,attrs,0);
}

public CustomView(Context context,AttributeSet attrs,int defStyleAttr){
    super(context,attrs,defStyleAttr);

    TypedArray array=context.getTheme().obtainStyledAttributes(attrs,R.styleable.CustomView,defStyleAttr);

    int count=array.getIndexCount();
    for(int i=0;i<count;i++){
        switch(i){
            case R.styleable.CustomView_attrs_text://声明:在styleable中它的名字为attrs_text
                text=array.getString(index);
                break;
            case R.styleable.CustomView_attrs_text_color:
                texcolor=array.getInt(index,Color.BLACK);
                break;
            case  R.styleable.CustomView_attrs_text_size:
                textsize=array.getDimensionPixelSize(index16);
                break;
            ......
    }       







关于TypedArrayAttributeSet

        AttributeSet的作用就是在控件进行初始化的时候,解析布局文件中该控件的属性(keyeg:background)与该值(valueeg:@drawable/icon)的信息封装在AttributeSet中,传递给该控件的构造函数。

        对于非Android自带的属性,在View类中处理时是无法识别的,需要我们自己解析。所以需要用到TypedArray。在AttributeSet中有属性名称和属性值,TypedArray的工作就是来告诉控件哪个属性代表什么意思。

        TypedArray对象封装了/values/attrs.xml中的styleable里定义的每个属性的类型信息,通过TypedArray就可以知道AttributeSet中封装的值的类型,从而可以对这些数据进行应用。

猜你喜欢

转载自blog.csdn.net/weixin_38664232/article/details/84768099