Android 自定义属性设置

在编写一个自定义控件时候,遇到一个通过自定义属性切换背景颜色需求,一开始我通过两个自定义属性来来设置不同状态下的颜色,然后通过代码逻辑进程选择切换,后来久想能不能通过selector,设置类似android:state_checked、android:state_enabled这类属性一样进行设置,通过测试,最后总算是实现。下面对一些步骤做一些记录和整理。

1 首先当然是需要对这些自定义属性进行创建声明,在values/attrs.xml中进行自定义属性命名如下:

自定义属性定义

2 我们在自定义控件中去接收对应的属性值并实现对应逻辑

      在自定义控件的构造方法中获取对应的属性值,因为其中csl_next_bg_color为颜色值,可能是两中状态,所以我们用ColorStateList对象进行接收。

获取属性值

        因为是通过next_enable属性进行设置获取,所以我们需要定义两个状态的数组,其中加负号为false状态,至于定义数组是因为我们从ColorStateList中获取对应颜色时候需要用到数组。其中要注意的是使用R.attr.id而不是向上面获取属性时候使用R.styleable.id,一开始没注意使用错了获取颜色时候老是不对(囧。。。)

设置不同状态参数值

  然后我们在自定义控件中重写onCreateDrawableState方法来创建对应不同状态的数组。

其中下面代码中“+1”表示添加一种自定义属性状态,如何设置多种就加几。然后通过类型状态创选取上面定义的数组进行初始化数组。

@Override

protected int[] onCreateDrawableState(int extraSpace) {

    int drawableState[] = super.onCreateDrawableState(extraSpace + 1);

    if (next_enable) {

        mergeDrawableStates(drawableState, NEXT_STATE_ENABLE);

    } else {

        mergeDrawableStates(drawableState, NEXT_STATE_DISABLE);

    }

    return drawableState;

}


接着我们就可以通过ColorStateListgetColorForState方法获取当前状态下的具体值了。其中getDrawableState()方法为父类方法,会调用我们重写的onCreateDrawableState的方法进行状态数组的获取。

private void upNextEnable() {

    if (csl_next_bg_color != null) {

        next_bg_color = csl_next_bg_color.getColorForState(getDrawableState(), 0);

    } else {

    }

}


最后在状态切换api中,我们需要重新刷新属性值并刷新界面。其中refreshDrawableState方法是父类方法,如果不调用会造成onCreateDrawableState方法中的状态数组没有被清理,从而造成数据错误。

public void setNextEnable(boolean enable) {

    if (next_enable != enable) {

        next_enable = enable;

        refreshDrawableState();

        upNextEnable();

        invalidate();

    }

}


3  最后我们只要在使用自定义控件时候编写selector设置颜色及在自定义控件引用时候进行设置就可以了


bg_select_color_is.xml

具体实现可以看git:https://gitee.com/zhengdd/MyWidget

你可能感兴趣的:(Android 自定义属性设置)