StateListDrawable
定义
Lets you assign a number of graphic images to a single Drawable and swap out the visible item by a string ID value.
可以设定多个图片到一个图片资源内,并且根据配置的R.drawble.id值转换出当前需可见的图片
实际理解是状态资源,根据当前绑定对象的状态匹配当前状态下需要显示的images
使用
defined in xml
以<selector 为根标签定义StateListDrawable,图形成员使用<item 为根标签定义,文件内包含一个或多个 元素。
drawable目录下 - New - Drawable Recource file创建
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android"
android:constantSize=["true" | "false"]
是否固定大小为item中的maxSize,否则大小随item变动;default false
android:dither=["true" | "false"]
是否启用抖动算法在位图的像素配置与屏幕不同时适配屏幕颜色渲染 default true
如:ARGB 8888 位图和 RGB 565 屏幕)
android:variablePadding=["true" | "false"] >
是否随state item变动,否:padding大小取item's maxSize,default false
<item
android:drawable="@[package:]drawable/drawable_resource" 图像资源 *必须配置
android:state_pressed=["true" | "false"] 是否按压状态
android:state_focused=["true" | "false"] 是否获取焦点状态
android:state_hovered=["true" | "false"] 光标是否悬停本对象状态,与获取焦点相似 api14引入
android:state_selected=["true" | "false"] 是否被勾选,子类蔓延影响父类
android:state_checkable=["true" | "false"] 是否可选状态 识别是否展示可供选择标记(如选择框)
android:state_checked=["true" | "false"] 此属性在checkable基础上判断的,是否已选
android:state_enabled=["true" | "false"] 是否可用,通过setEnable可配置状态
android:state_activated=["true" | "false"]
是state_checked的另一种表示形式,是能传递到子类的状态,可通过代码 setActivated改变
android:visible =["true" | "false"] 是否可见
android:state_window_focused=["true" | "false"] />
当应用窗口有焦点,显示在前台 true;(如:通知栏下拉或对话框出现)状态值为false
</selector>
匹配规则
根据对象当前状态从上往下匹配,符合的第一个item即显示。
因此默认状态往往放在最后一项,以便对比过滤完所有状态条件
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true"
android:drawable="@drawable/button_pressed" /> <!-- pressed -->
<item android:state_focused="true"
android:drawable="@drawable/button_focused" /> <!-- focused -->
<item android:state_hovered="true"
android:drawable="@drawable/button_focused" /> <!-- hovered -->
<item android:drawable="@drawable/button_normal" /> <!-- default -->
</selector>
组件常见使用
选择按钮:state_checked,state_selected
普通按钮:state_clickable,state_pressed(按压过程中)
文本:state_focused,state_enabled
状态通过用户行为或直接代码设定
create in code
StateListDrawable内部主要使用StateListSet记录状态列,沿用父类的drawble[]保存图形资源
StateListDrawable drawable = new StateListDrawable();
Drawable unSelected = ImageUtil.getVectorDrawableCompat(context, normalResId);
Drawable selected = ImageUtil.getVectorDrawableCompat(context, activeResId);
drawable.addState(new int[]{-android.R.attr.state_selected},unSelected);//负值表示false
drawable.addState(new int[]{android.R.attr.state_focused},selected);
drawable.addState(new int[]{android.R.attr.state_selected},selected);
drawable.addState(new int[]{android.R.attr.state_pressed},selected);
//没有任何状态下配置的drawable,使用空集合
drawable.addState(new int[]{}, getDrawable(android.R.attr.state_enabled));
源码
public void addState(int[] stateSet, Drawable drawable) {
if (drawable != null) {
mStateListState.addStateSet(stateSet, drawable);
// in case the new state matches our current state...
onStateChange(getState());//获取当前组件状态列,切换当前状态下需要显示的drawable
}
}
@Override
protected boolean onStateChange(int[] stateSet) {
final boolean changed = super.onStateChange(stateSet);
int idx = mStateListState.indexOfStateSet(stateSet);//匹配状态
if (DEBUG) android.util.Log.i(TAG, "onStateChange " + this + " states "
+ Arrays.toString(stateSet) + " found " + idx);
if (idx < 0) {
idx = mStateListState.indexOfStateSet(StateSet.WILD_CARD);//取默认状态
}
return selectDrawable(idx) || changed;
}
StateListState内源码 - StateListSet初始默认为[10][ ]大小
int addStateSet(int[] stateSet, Drawable drawable) {
final int pos = addChild(drawable);//往drawable[]的末尾添加当前drawable对象
mStateSets[pos] = stateSet;//往状态列的特定位置 把当前新增状态列赋值。即内容指向int[]
return pos;
}
即当你配置使用StateListDrawable,会直接显示当前状态的Drawable.
常用作于tab,按钮背景等