android 动态设置color,如何为控件动态设置ColorSelector

危寒
2023-12-01

其实一开始,在简书上写东西我是拒绝的!怕被拍砖,后来发现邻桌的郭老师时不时写写简书,我才意识到,原来什么样的人都可以写简书,充分说明简书的读者还是很包容的。胆战心惊,写下第一篇简书,主要是为了和大家共同分享记录开发中的点点滴滴(好吧,其实我是记性差,想写写笔记,但是字太丑,纸质的写完没几天自己都不认识了!)

今天要分享的内容不多,主要是和大家分享一下如何在代码中动态设置ColorSelector,作为一名开发人员,在XML中无论是配置background的selector还是color的selector,都应该是我们的基本功。XML中控件的属性一般也都对应动态的方法,eg: android:text="R.string.register"对应着setText()方法,这样的对应有很多。废话不多说,说问题,上代码。

使用selctort的控件:

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:background="@drawable/selector_choose_grade_bg"

android:button="@null"

android:padding="2dp"

android:gravity="center"

android:text="1年级"

android:textColor="@color/selector_grade_color" />```

可以看到,这是个RadioButton控件(废话),是使用了两个selector,在XML中使用selector的时候,只要selector不写错,肯定没有问题。但是,测试妹子提了个要求,为了实现这个需求,需要动态给控件设置selector,我们知道,background在代码中设置selector是没有问题的,但是textColor呢?我也没试过,于是我就惯性思维的调了个setTextColor(int color)的方法,参数直接为selector,结果可想而知,是失败的,要不我还来废话干啥?发现当某个RadioBUtton的textSelector不起作用,刚开始,我也很纳闷,但是发现了个setTextColor(ColorStateList colors),这是个什么?当然是颜色集合啦,那么这两个重载方法有什么区别呢?为了写好这篇帖子,硬着头皮去读源码(读源码就想吐,有高手请指教)。

源码如下:

/**

Sets the text color for all the states (normal, selected, * focused) to be this color.

@see #setTextColor(ColorStateList)

@see #getTextColors()

@attr ref android.R.styleable#TextView_textColor

/

@android.view.RemotableViewMethod

public void setTextColor(@ColorInt int color) {

mTextColor = ColorStateList.valueOf(color);

updateTextColors();}

/* * Sets the text color.

@see #setTextColor(int)

@see #getTextColors()

@see #setHintTextColor(ColorStateList)

@see #setLinkTextColor(ColorStateList)

@attr ref android.R.styleable#TextView_textColor

*/

public void setTextColor(ColorStateList colors) {

if (colors == null) {

throw new NullPointerException();

}

mTextColor = colors;

updateTextColors();

}

可以看到两个重载方法的内部最终都是把传进的参数转成了ColorStateList集合,那为什么我用第一种重载不行呢?当我把第一种方法valueof()方法的源码点下去,发现:

/**

**@return A ColorStateList containing a single color.

*/

@NonNull

public static ColorStateList valueOf(@ColorInt int color) {

synchronized (sCache) {

final int index = sCache.indexOfKey(color);

if (index >= 0) {

final ColorStateList cached = sCache.valueAt(index).get();

if (cached != null) {

return cached;

}

// Prune missing entry.

sCache.removeAt(index);

}

// Prune the cache before adding new items.

final int N = sCache.size();

for (int i = N - 1; i >= 0; i--) {

if (sCache.valueAt(i).get() == null) {

sCache.removeAt(i);

}

}

final ColorStateList csl = new ColorStateList(EMPTY, new int[] { color });

sCache.put(color, new WeakReference<>(csl));

return csl;

}

}```

看到,注释中说的很清楚了,调用该方法返回的集合只包含一种颜色,这也就解释了为什么我的textSelector使用这个方法的时候不奏效了!就算你selector中的item写得再多,虽然它也是把咱们的selector最终转化为ColorStateList 来设置字体颜色,但是setTextColor(@ColorInt int color) 只返回第一种颜色!我们可以通过context.getResources().getColorStateList(R.color.selector名)来获取ColorStateList 对象作为参数传进我们的setTextColor(ColorStateList colors)方法中!

最后,刚下笔写简书的时候郭老师告诉我写着太麻烦,我不信,写了下来发现确实不太方便,尤其是代码格式化,是我一个一个回车敲出来的(可能我太low了)!希望大家给予支持!如果大家有好的稿件或资源,也麻烦大家动动你的小手指分享出来呦!附上我的邮箱:huangpenfy@163.com

 类似资料: