前言
一般我們建立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>?r-:r);
g = (g>?g-:g);
b = (b>?b-:b);
int checkColor = Color.argb(, 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” 實際效果如下圖
沒有按下去的 | 按下去的 |
---|---|