相信很多开发者说到Android的选择器,第一时间相到应该就是selector了吧,而应用的最多的应该就是用于同步切换View的背景了吧,往往有些忽略了selector不仅仅可以用于切换背景也可以动态改变View的颜色,当然这并不是什么很复杂的知识点。不过我想总结下这篇文章并不是因为这个原因,今天在自定义一个View的时候,获取对应的颜色值并设置到TextView上,一个setTextColor(int )让我很迷惑,(有些颜色只用五位整数来表达,而有的颜色却用了八位而且还都带一个负号“-”,不是我们普通认知的RGB或者其他模式),追踪源码发现了ColorStateList对象…
StateListDrawable作为Drawable系中重要的一员家族成员,该类定义了不同状态值下与之对应的图片资源,即我们可以利用该类保存多种状态android:state_pressed、android:state_checkable、android:state_selected、android:state_focused、android:state_enabled、android:state_window_focused、android:state_checked、android:state_first 、android:state_active 、android:state_last 、android:state_middle 值,多种图片资源。
StateListDrawable也是一个图片资源,也会和其他字符串一样再R文件中自动生成。
res/drawable/filename.xml
方法名 | 说明 |
---|---|
public StateListDrawable() | 构造方法 |
void addState(int[] stateSet, Drawable drawable) | 给特定的状态集合设置drawable资源,其中“-”负号表示对应的属性值为false |
void inflate(Resources r, XmlPullParser parser, AttributeSet attrs) | |
从XML资源中加载对应的Drawable | |
boolean isStateful() | 当状态改变的时候是否同步改变对应的Drawable,true则同步改变 |
状态属性值 | 含义 |
---|---|
android:state_active | 是否处于激活状态 |
android:state_checkable | 是否可勾选 |
android:state_checked | 是否已勾选 |
android:state_enabled | 是否可用 |
android:state_first | 是否开始状态 |
android:state_focused | 是否已得到焦点 |
android:state_last | 是否处于结束 |
android:state_middle | 是否处于中间 |
android:state_pressed | 是否处于按下状态 . |
android:state_selected | 是否处于选中状态 |
android:state_window_focused | 是否窗口已获得焦点 |
"1.0" encoding="utf-8"?>
"http://schemas.android.com/apk/res/android"
android:constantSize=["true" | "false"]
android:dither=["true" | "false"]
android:variablePadding=["true" | "false"] >
- "@[package:]drawable/drawable_resource"
android:state_pressed=["true" | "false"]
android:state_focused=["true" | "false"]
android:state_hovered=["true" | "false"]
android:state_selected=["true" | "false"]
android:state_checkable=["true" | "false"]
android:state_checked=["true" | "false"]
android:state_enabled=["true" | "false"]
android:state_activated=["true" | "false"]
android:state_window_focused=["true" | "false"] />
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true"
android:drawable="@drawable/button_pressed" />
<item android:state_focused="true"
android:drawable="@drawable/button_focused" />
<item android:state_hovered="true"
android:drawable="@drawable/button_focused" />
<item android:drawable="@drawable/button_normal" />
selector>
<Button
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:background="@drawable/button" />
//初始化一个空对象
StateListDrawable stalistDrawable = new StateListDrawable();
//获取对应的属性值 Android框架自带的属性 attr
int pressed = android.R.attr.state_pressed;
int window_focused = android.R.attr.state_window_focused;
int focused = android.R.attr.state_focused;
int selected = android.R.attr.state_selected;
stalistDrawable.addState(newint []{pressed , window_focused}, getResources().getDrawable(R.drawable.pic1));
stalistDrawable.addState(newint []{pressed , -focused}, getResources().getDrawable(R.drawable.pic2);
stalistDrawable.addState(newint []{selected }, getResources().getDrawable(R.drawable.pic3);
stalistDrawable.addState(newint []{focused }, getResources().getDrawable(R.drawable.pic4);
//没有任何状态时显示的图片,我们给它设置我空集合
stalistDrawable.addState(newint []{}, getResources().getDrawable(R.drawable.pic5);
ColorStateList直接继承Object通过实现Parcelable接口达到序列化,虽然不是Drawable系的子类,但是其实也可以看成是一个Drawable对象。从字面命名理解就可以知道这是一个与状态相关的,是一个可以在资源文件里/res/color中定义的对象,可以根据View对象的android:state_pressed、android:state_checkable、android:state_selected、android:state_focused、android:state_enabled、android:state_window_focused、android:state_checked状态变化同步切换对应的颜色。 比如,Button可以存在于几种不同状态之一(按下,聚焦或更靠近),通过使用颜色状态列表ColorStateList,我们可以在各个状态期间同步切换不同的颜色。简而言之,它是我们的一种selector。
ColorStateList也是一个资源,也会和其他字符串、图片资源一样再R文件中自动生成。
res/color/filename.xml
android:color
#RGB
#ARGB
#RRGGBB
#AARRGGBB
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_focused="true" android:color="@color/testcolor1"/>
<item android:state_pressed="true" android:state_enabled="false" android:color="@color/testcolor2" />
<item android:state_enabled="false" android:color="@color/testcolor3" />
<item android:color="@color/testcolor5"/>
selector>
状态属性值 | 含义 |
---|---|
android:state_checkable | 是否可勾选 |
android:state_checked | 是否已勾选 |
android:state_enabled | 是否可用 |
android:state_focused | 是否已得到焦点 |
android:state_pressed | 是否处于按下状态 . |
android:state_selected | 是否处于选中状态 |
android:state_window_focused | 是否窗口已获得焦点 |
方法名 | 说明 |
---|---|
public ColorStateList(int[][] states, int[] colors) | 构造方法 |
static ColorStateList createFromXml(Resources r, XmlPullParser parser) | 通过xml资源文件建立对应的ColorStateList对象 |
int getColorForState(int[] stateSet, int defaultColor) | |
获取状态对应的颜色 | |
int getDefaultColor() | |
static ColorStateList valueOf(int color) | 把代表颜色的整数转为ColorStateList |
res/color/button_text.xml
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true"
android:color="#ffff0000"/>
<item android:state_focused="true"
android:color="#ff0000ff"/>
<item android:color="#ff000000"/>
selector>
Button btn=(Button)findViewById(R.id.btn);
Resources resource=(Resources)getBaseContext().getResources();
ColorStateList colors=(ColorStateList)resource.getColorStateList(R.color.btn_text);
if(colors!=null){
btn.setTextColor(color_state_list);//设置按钮文字颜色
}
XmlResourceParser xpp=Resources.getSystem().getXml(R.color.button_text);
try {
ColorStateList colors= ColorStateList.createFromXml(getResources(),xpp);
btn.setTextColor(colors);
} catch (Exception e) {
}
/**
*千万不能把自己定义的颜色直接当成参数,例如:
tv.setTextColor(R.color.red);这种情况会出现颜色错误!
**/
"red">#FF0000
< drawable name="red">#FF0000
< string name="red">#FF0000