Android 代码动态设置TextView的背景、颜色Selector

在Android里面,实现TextView等根据不同状态显示不同的背景和颜色是很简单滴,只需要设置对应的selector就好了!
背景选择器(res/drawable):


    
    

颜色选择器(res/color):


    
    
    
    

那么我们需要动态设置这些东西怎么写呢?这里就有两个类了:StateListDrawable,ColorStateList看这个名字就知道这两个类是来干嘛的了!

首先说下StateListDrawable
创建对应的StateListDrawable,通过addState (int[] stateSet, Drawable drawable)的方法添加我们指定的一些状态,可以看到第一个参数是一个数组,后面就是对应的Drawable。那么问题来了,一个状态的true或者false是怎么指定的呢?答案就是下面这个样子滴:

    StateListDrawable states = new StateListDrawable();
    states.addState(new int[]{-android.R.attr.state_checked}, getDrawable(android.R.drawable.ic_media_play));
    states.addState(new int[]{android.R.attr.state_checked}, getDrawable(android.R.drawable.ic_delete));
    return states;

前面有一个负号就是false的状态!

然后就是ColorStateList了,它的构造方法public ColorStateList(int[][] states, @ColorInt int[] colors),看着是不是有点儿腻害,颜色状态居然指定的是一个二维的数组,刚刚上面不是都才指定一个一维的数组嘛,为什么这里就是一个二维的呢?第二个参数也是一个color的数组。

其实可以这样理解,就是把上面说的一个状态和一个color又分别装到了一个数组中了,所以维度都对应增加了1,这样我们就不用去添加好几次了,注意上面的写法,每一种状态我们都需要添加一次的!!

那么套路明确了之后就可以把上面的写法改造一下,比如说第一个参数一个二维数组:

    int[][] states = new int[][]{
            new int[]{-android.R.attr.state_checked}, // unchecked
            new int[]{android.R.attr.state_checked}  // checked
    };//把两种状态一次性添加

第二个参数每个状态对应的颜色:

    int[] colors = new int[]{
            Color.RED,
            Color.GREEN
    };//把两种颜色一次性添加

最后再调用构造方法就好啦!!

ColorStateList colorStateList = new ColorStateList(states, colors);

最后,再说说给TextView及它的小弟动态设置CompoundDrawable的问题,这个就是在xml中设置的那个drawableTopdrawableBottom、等等!

这里需要注意一个问题,就是我们代码new出来的Drawable的Bound是没有指定好的,那么导致的问题就是它可能根本就不会绘制的!!

Android 代码动态设置TextView的背景、颜色Selector_第1张图片
setCompoundDrawables.png

解决办法就是你可以直接调用setCompoundDrawablesRelativeWithIntrinsicBounds()这个老长老长的方法让系统自动去设置那个Bound的参数!

@android.view.RemotableViewMethod
public void setCompoundDrawablesRelativeWithIntrinsicBounds(@Nullable Drawable start,
        @Nullable Drawable top, @Nullable Drawable end, @Nullable Drawable bottom) {

    if (start != null) {
        start.setBounds(0, 0, start.getIntrinsicWidth(), start.getIntrinsicHeight());
    }
    if (end != null) {
        end.setBounds(0, 0, end.getIntrinsicWidth(), end.getIntrinsicHeight());
    }
    if (top != null) {
        top.setBounds(0, 0, top.getIntrinsicWidth(), top.getIntrinsicHeight());
    }
    if (bottom != null) {
        bottom.setBounds(0, 0, bottom.getIntrinsicWidth(), bottom.getIntrinsicHeight());
    }
    setCompoundDrawablesRelative(start, top, end, bottom);
}

当然你也可以老老实实在创建StateListDrawable的时候手动调用一下setBound()的方法啦!!

到此结束!!希望大家不要再掉到对应的坑里面了!!

---- Edit By Joe ----

你可能感兴趣的:(Android 代码动态设置TextView的背景、颜色Selector)