前言
一般我们创建Selector是通过XML文件来创建,然后在XML文件中的某个控件指定background引用此Selector;但有些时候,我们需要通过代码来动态设置Selector:
比如说GridView中的item数量不确定,而且每个Item的背景颜色是不一样的,每个item对应的数据都有颜色的,那么我们就不能用同一个Selector来设置,这时候就需要动态创建Selector。
分析
item有两种状态:按下去,没有按下去;
针对这两种状态应该准备两种颜色,一般按下去的效果是颜色更深一些,那么颜色值就应该减少(这种规律 我们可以推理出来的:白色#FFFFFF 黑色#000000,值越来越小颜色就越来越深,到最后变成黑色)
这时有人会想直接将原有颜色值减去固定值 不就是按下去的效果嘛,这样简单的相减肯定不行:
因为在Android里面,颜色值的表示是通过8位十六进制,前两位表示透明度,后六位分别两两表示R,G,B(R红 占两位,G绿占两位 , B蓝占两位),
R 0~255(00 - FF)
G 0~255(00 - FF)
B 0~255(00 - FF)
我们应该对每一位进行减去一个固定值,而且该位的值大于该固定值才相减,否则变成负数,
这里假设item对应的数据给出了颜色:(没有按下去时,正常状态时的)
假设颜色值是(8位十六进制表示) #FFFF0000
实现
这里我给出了GridView的Adapter里面的getView方法的部分设置Color Selector代码
@Override
public View getView(final int position, View convertView, ViewGroup parent)
{
...
if(iconLink.backgroundColor != null)
{
int color;
try
{
//这里iconLink 里面的backgroundColr是8位十六进制字符串(带#)
//Eg: #FF000000
color = Color.parseColor(iconLink.backgroundColor);
//注意为了兼容低版本这里使用setBackgroundDrawable而不是setBackground
convertView.setBackgroundDrawable(**createStateListDrawable**(color));
}
catch (Exception e)
{
e.printStackTrace();
}
}
return convertView;
}
/**
* 创建Color Selector
* @param normalColor 正常状态时的颜色
* @return StateListDrawable
*/
private StateListDrawable createStateListDrawable(int normalColor)
{
StateListDrawable drawable = new StateListDrawable();
int r = Color.red(normalColor);
int g = Color.green(normalColor);
int b = Color.blue(normalColor);
r = (r>20?r-20:r);
g = (g>20?g-20:g);
b = (b>20?b-20:b);
int checkColor = Color.argb(255, r, g, b);
//Pressed按下去时的颜色
drawable.addState(new int[]{android.R.attr.state_pressed},
new ColorDrawable(checkColor));
//Unpressed 没有按下去,这里用负数(注意里面的“-”号),对应XML设定是
false时,就需要使用资源符号的负值来设定。
drawable.addState(new int[]{-android.R.attr.state_pressed},new
ColorDrawable(normalColor));
return drawable;
}
从以上代码可以看出:对R,G,B的每位减去20,且增加了大于20相减的判断,StateListDarawable添加了两个Drawable,一个是按下去的ColorDrawale,一个是没有按下去的ColorDrawable
这里iconLink 里面的backgroundColr = “#FFD74968” 实际效果如下图
没有按下去的 | 按下去的 |
---|---|