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

参考: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为单位的。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值