手把手写Android自定义控件(二):自定义属性的定义与获取

上一篇讲解了如何创建项目和库,本篇来讲解如何给自定义控件定义属性。

属性定义

首先我们在widgetlib的下创建一个类叫Switch(开关),继承于View,让它继承View的全部构造函数。
在这里插入图片描述在这里插入图片描述

接着在values文件夹下创建一个属性声明文件,名字叫attr_switch,一般命名的规则是attr_xxx,表示某控件的属性声明。
在这里插入图片描述
文件创建好了,接下我们想想这个控件需要定义什么属性,结合下面的图片来看看。
在这里插入图片描述
1.开关打开的颜色(蓝色部分)
2.开关关闭的颜色(灰色部分)
3.开关的底色(红色)
4.开关凹槽的颜色(绿色)

在想想看还需要什么属性呢?能设置的属性越多,这个控件diy的空间就越大。想想看Android Studio自带的TextView,光是一个文本框就有十几种可设置的属性。

5.控制开关大小的内间距(paddingSwitch)
6.控制凹槽的内间距(paddingInside)
7.开关底部的半径(radius)
在这里插入图片描述
目前想到的属性就这么多,接下来我们在attr_switch.xml属性文件上声明它们。

<resources>
    <declare-styleable name="Switch">
        <attr name="OnColor" format="color"/>
        <attr name="OffColor" format="color"/>
        <attr name="InsideColor" format="color"/>
        <attr name="BackColor" format="color"/>
        
        <attr name="SwitchPadding" format="dimension"/>
        <attr name="InsidePadding" format="dimension"/>
        <attr name="radius" format="dimension"/>
    </declare-styleable>
</resources>

declare-styleable 标签是用来绑定控件对应的java文件的。
attr 标签就是用来声明自定义控件属性的,其中name是属性名,format是属性的类型。color是颜色类型,dimension是尺寸类型。

这么一来,属性声明就完成了。我们来试试看是不是定义成功了。

打开app上的MainActivity布局文件。
在这里插入图片描述
如果会提示刚刚创建Switch控件,说明目前是成功的了。
在这里插入图片描述
在布局文件上放一个我们定义的Switch。注意,由于这些属性是我们自己定义的,而不是Android自带的,所以要在最外层布局加上
xmlns:app=“http://schemas.android.com/apk/res-auto”

自定义属性用app:

<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <com.pyjtlk.widgetlib.Switch
        android:layout_width="100dp"
        android:layout_height="20dp"
        app:BackColor="#AA00"
        app:InsideColor="#A0A0"
        app:OffColor="#AAAAAA"
        app:OnColor="#A00A"
        app:InsidePadding="5dp"
        app:SwitchPadding="3dp"
        app:radius="20dp"/>

</LinearLayout>

获取自定义属性

给Switch设置了这么多自定义属性,下面就要获取它们的值,回到Switch.java。

先定义这些私有变量来接收刚刚布局文件上的参数。

public class Switch extends View {
    private int mInsideColor;
    private int mOnColor;
    private int mOffColor;
    private int mBackColor;

    private int mSwitchPadding;
    private int mInsidePadding;
    private int mRadius;
    ...

接着写一个初始化方法。

private void getAttrFromXml(Context context,AttributeSet attrs){
        //1
        TypedArray typedArray = context.obtainStyledAttributes(attrs,R.styleable.Switch);

        //2
        mInsideColor = typedArray.getColor(R.styleable.Switch_InsideColor, Color.GREEN);
        mOnColor = typedArray.getColor(R.styleable.Switch_OnColor, Color.BLUE);
        mOffColor = typedArray.getColor(R.styleable.Switch_OffColor, Color.GRAY);
        mBackColor = typedArray.getColor(R.styleable.Switch_BackColor, Color.RED);

        //3
        mSwitchPadding = typedArray.getDimensionPixelSize(R.styleable.Switch_SwitchPadding,0);
        mInsidePadding = typedArray.getDimensionPixelSize(R.styleable.Switch_InsidePadding,0);
        mRadius = typedArray.getDimensionPixelSize(R.styleable.Switch_radius,0);

        //4
        typedArray.recycle();
}

先看到代码1和代码4。代码1、代码4分别是打开xml文件和关闭xml文件,在它们之间就是获取参数的操作。

注释2下面的四行代码获取控件定义的颜色属性,颜色值在xml文件的格式是#AABBCCDD,到了java文件上就被转换为整型了。

注释3下面的三行代码获取控件定义的尺寸属性,尺寸属性在xml文件的单位可以是dp、sp、px等,通过getDimensionPixelSize方法可以将其转换为对应的像素个数。

举个例子,如果dp和像素的比例是3:1,那么在xml文件上设置10dp,通过getDimensionPixelSize就的到30,也就是30个像素。

获取到参数了,把它放在构造函数上就行了。

    public Switch(Context context) {
        super(context);
    }

    public Switch(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        getAttrFromXml(context,attrs);
    }

    public Switch(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        getAttrFromXml(context,attrs);
    }

    public Switch(Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
        getAttrFromXml(context,attrs);
    }

为什么不放在第一个构造函数里呢?因为在java文件里动态生成控件才会用到第一个构造方法。

至此,自定义属性的定义和获取就完成了,但对于整个控件的初始化来说这只是其中很小的一部分,还有很多的工作要做。

最后

下一篇将讲解如何测量控件宽高与绘制。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值