Drawable和stateSet的关系
state实际上就是一个整型数组,你可以追加各种state,比如state_press、state_press。
用xml生成Drawable
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_checked="true" android:drawable="@drawable/on_switch" />
<item android:drawable="@drawable/off_switch" />
</selector>
以上代码可以生成一个根据状态改变的Drawable,如果当前state为checked的话,则真实的Drawable为on_switch,否则为off_switch。
怎么刷新Drawable的state
Drawable.java里有一个方法,可以用来设置state:
public boolean setState(@NonNull final int[] stateSet) {
if (!Arrays.equals(mStateSet, stateSet)) {
mStateSet = stateSet;
return onStateChange(stateSet);
}
return false;
}
实例
android自带的CompoundButton就是用的Drawable的state来实现的。当我们调用它的setChecked方法时:
public void setChecked(boolean checked) {
if (mChecked != checked) {
mCheckedFromResource = false;
mChecked = checked;
refreshDrawableState();
...
会调用View.refershDrawableState方法:
public void refreshDrawableState() {
mPrivateFlags |= PFLAG_DRAWABLE_STATE_DIRTY;
drawableStateChanged();
ViewParent parent = mParent;
if (parent != null) {
parent.childDrawableStateChanged(this);
}
}
protected void drawableStateChanged() {
final int[] state = getDrawableState();
boolean changed = false;
final Drawable bg = mBackground;
if (bg != null && bg.isStateful()) {
changed |= bg.setState(state);
}
final Drawable hl = mDefaultFocusHighlight;
if (hl != null && hl.isStateful()) {
...
继而会通过getDrawableState()获取当前View的state:
public final int[] getDrawableState() {
...
mDrawableState = onCreateDrawableState(0);
return mDrawableState;
}
回到,CompoundButton,它重写了设置state的方法:
@Override
protected int[] onCreateDrawableState(int extraSpace) {
final int[] drawableState = super.onCreateDrawableState(extraSpace + 1);
if (isChecked()) {
mergeDrawableStates(drawableState, CHECKED_STATE_SET);
}
return drawableState;
}
将Drawable设置为state_checked状态。这个时候还没有刷新Drawable,刷新的逻辑是在下面,CompoundButton监听了stateChange事件:
@Override
protected void drawableStateChanged() {
super.drawableStateChanged();
final Drawable buttonDrawable = mButtonDrawable;
//设置状态
if (buttonDrawable != null && buttonDrawable.isStateful()
&& buttonDrawable.setState(getDrawableState())) {
//刷新Drawable的显示
invalidateDrawable(buttonDrawable);
}
}
博客探讨了Drawable与stateSet之间的关系,如何使用xml创建根据状态变化的Drawable,并详细解释了如何刷新Drawable的状态。文中通过实例展示了在CompoundButton中如何利用Drawable的state实现切换效果,当调用setChecked方法时,会更新Drawable的状态并触发刷新。
824

被折叠的 条评论
为什么被折叠?



