自定义view-构造方法和自定义属性

来源:互联网 发布:网络教育专升本院校 编辑:程序博客网 时间:2024/04/30 16:43

参考:Android自定义View(二、深入解析自定义属性)

自定义属性:values/attrs.xml

<?xml version="1.0" encoding="utf-8"?><resources>    <declare-styleable name="CustomView">        <!--color-->        <attr name="textColor" format="color" />        <!--dimension-->        <attr name="layout_width" format="dimension" />        <!--boolean-->        <attr name="focusable" format="boolean" />        <!--enum-->        <attr name="orientation">            <enum name="horizontal" value="0" />            <enum name="vertical" value="1" />        </attr>        <!--flag-->        <attr name="gravity">            <flag name="top" value="0x30" />            <flag name="bottom" value="0x50" />            <flag name="left" value="0x03" />            <flag name="right" value="0x05" />            <flag name="center_vertical" value="0x10" />        </attr>        <!--float-->        <attr name="fromAlpha" format="float" />        <!--fraction-->        <attr name="pivotX" format="fraction" />        <!--integer-->        <attr name="framesCount" format="integer" />        <!--reference-->        <attr name="background" format="reference" />        <!--string-->        <attr name="text" format="string" />        <!--系统自带属性-->        <attr name="android:text" />    </declare-styleable></resources>

format支持的类型一共有11种:
color
dimension
boolean
enum
flag
float
fraction
integer
reference
string

(1). reference:参考某一资源ID,带有@

属性定义:

    <declare-styleable name = "名称">         <attr name = "background" format = "reference" />    </declare-styleable>

属性使用:

<ImageView android:background = "@drawable/图片ID"/>

(2). color:颜色值

属性定义:

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

属性使用:

<TextView android:textColor = "#00FF00" />

(3). boolean:布尔值

属性定义:

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

属性使用:

<Button android:focusable = "true"/>

(4). dimension:尺寸值(带单位)

属性定义:

<attr name = "layout_width" format = "dimension" />

属性使用:

<Button android:layout_width = "42dip"/>

(5). float:浮点值

属性定义:

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

属性使用:

<alpha android:fromAlpha = "1.0"/>

(6). integer:整型值

属性定义:

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

属性使用:

<animated-rotate android:framesCount = "12"/>

(7). string:字符串

属性定义:

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

属性使用:

<TextView android:text = "我是文本"/>

(8). fraction:百分数

属性定义:

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

属性使用:

<rotate android:pivotX = "200%"/>

(9). enum:枚举值

属性定义:

    <declare-styleable name="名称">        <attr name="orientation">            <enum name="horizontal" value="0" />            <enum name="vertical" value="1" />        </attr>    </declare-styleable>

属性使用:

  <LinearLayout        android:orientation = "vertical">    </LinearLayout>

注意:枚举类型的属性在使用的过程中只能同时使用其中一个,不能 android:orientation = “horizontal|vertical”

(10). flag:位或运算

属性定义:

    <declare-styleable name="名称">        <attr name="gravity">                <flag name="top" value="0x30" />                <flag name="bottom" value="0x50" />                <flag name="left" value="0x03" />                <flag name="right" value="0x05" />                <flag name="center_vertical" value="0x10" />                ...        </attr>    </declare-styleable>

属性使用:

<TextView android:gravity="bottom|left"/>

注意:位运算类型的属性在使用的过程中可以使用多个值

(11). 混合类型:属性定义时可以指定多种类型值

属性定义:

<declare-styleable name = "名称">         <attr name = "background" format = "reference|color" />    </declare-styleable>

属性使用:

    <ImageView android:background = "@drawable/图片ID" />    或者:    <ImageView android:background = "#00FF00" />

(12). 系统属性

我们在自定义View的时候,可以使用系统已经定义的属性。

 <declare-styleable name="test">        <attr name="android:text" /> </declare-styleable>

注意,
这里我们是使用已经定义好的属性,不需要去添加format属性(注意声明和使用的区别,差别就是有没有format)。
然后在类中这么获取:

ta.getString(R.styleable.test_android_text);

布局文件中直接使用:

android:text="@string/hello_world"

CustomView

public class CustomView extends View {    private static final String TAG = "CustomView";    /**     * 一个参数的构造方法:直接New一个View的时候调用。     */    public CustomView(Context context) {        this(context, null);    }    /**     * 两个参数的构造方法:layout布局文件中使用的时候会调用,     * <p>     * 关于它的所有属性(包括自定义属性)都会包含在attrs中传递进来。     *     * @param attrs:AttributeSet可以获得布局文件中定义的所有属性的key和value     */    public CustomView(Context context, @Nullable AttributeSet attrs) {        this(context, attrs, 0);    }    /**     * 三个参数的构造方法:这个构造方法系统是不调用的,需要我们显示调用并给defStyleAttr传值,     * 多了一个defStyleAttr参数,这是这个view引用style资源的属性参数,     * 也就是我们可以在style中为自定义View定义一个默认的属性样式然后添加进来!     *     * @param defStyleAttr:     * 默认的Style是指它在当前Application或Activity所用的Theme中的默认Style,      * 且只有在明确调用的时候才会生效     */    public CustomView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {        this(context, attrs, defStyleAttr, 0);    }    /**     * 有四个参数的构造函数在API21的时候才添加上     *     * @param context     * @param attrs     * @param defStyleAttr     * @param defStyleRes     */    public CustomView(Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {        super(context, attrs, defStyleAttr, defStyleRes);         //自定义属性的获取:        TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.CustomView);        TypedArray ta2 = context.obtainStyledAttributes(attrs, R.styleable.CustomView,defStyleAttr,defStyleRes);        int color1 = ta.getColor(R.styleable.CustomView_textColor, Color.parseColor("#ff0000"));        int color2 = ta.getColor(R.styleable.CustomView_textColor, Color.BLACK);        float dimension = ta.getDimension(R.styleable.CustomView_layout_width, 30f);        int dimensionPixelOffset = ta.getDimensionPixelOffset(R.styleable.CustomView_layout_width, 30);        int dimensionPixelSize = ta.getDimensionPixelSize(R.styleable.CustomView_layout_width,30);        boolean aBoolean = ta.getBoolean(R.styleable.CustomView_focusable, true);        String string = ta.getString(R.styleable.CustomView_text);        float aFloat = ta.getFloat(R.styleable.CustomView_fromAlpha,0.5f);        int integer = ta.getInteger(R.styleable.CustomView_framesCount, 1);        float fraction = ta.getFraction(R.styleable.CustomView_pivotX, 120, 240, 0.5f);        ta.recycle();    }}

参考:Android 深入理解Android中的自定义属性

TypedArray与AttributeSet的区别:

相同点:
获得布局文件中定义的所有属性的key和value

不同点:
TypedArray:直接获取值,用来简化我们的工作的。
AttributeSet:引用类型, 先获取id,再解析id

我们在View的构造方法中,
可以通过AttributeSet去获得自定义属性的值,但是比较麻烦,而TypedArray可以很方便的便于我们去获取。

参考:
getDimension,getDimensionPixelOffset和getDimensionPixelSize的区别
getDimension,getDimensionPixelOffset,getDimensionPixelSize

getDimension,getDimensionPixelOffset和getDimensionPixelSize的区别:

共同点:

都会根据density将其他单位dp,sp的数值转为px,px单位的保持不变。

不同点:

getDimension返回的是单位是px的float,不对值进行任何处理,
getDimensionPixelSize是返回int (px单位),小数部分进行四舍五入,
getDimensionPixelOffset是返回int(px单位),将结果直接截断小数位,抹去小数部分

控件里面从xml中获取的dimens的大小都是通过getDimensionPixelSize(四舍五入)来转换成px为单位的。