点击ViewGroup的空白区域,子View会变为点击态的bug原因及修复:
原因:在ViewGroup被点击时,会触发setPressed(boolean pressed)方法,如下:
public void setPressed(boolean pressed) {
final boolean needsRefresh = pressed != ((mPrivateFlags & PFLAG_PRESSED) == PFLAG_PRESSED);
if (pressed) {
mPrivateFlags |= PFLAG_PRESSED;
} else {
mPrivateFlags &= ~PFLAG_PRESSED;
}
if (needsRefresh) {
refreshDrawableState();
}
dispatchSetPressed(pressed);
}
执行完refreshDrawableState()刷新ViewGroup的背景之后会调用dispatchSetPressed(pressed)来讲press状态分发给子类处理
@Override
protected void dispatchSetPressed(boolean pressed) {
final View[] children = mChildren;
final int count = mChildrenCount;
for (int i = 0; i < count; i++) {
final View child = children[i];
// Children that are clickable on their own should not
// show a pressed state when their parent view does.
// Clearing a pressed state always propagates.
if (!pressed || (!child.isClickable() && !child.isLongClickable())) {
child.setPressed(pressed);
}
}
}
从代码可以看出如果子view的clickable == false && longclickable == false的情况下,子view会调用自己的setPressed(pressed)方法,来刷新自己的背景,如果子view的背景是一个StateListDrawable的话就会显示出处于press状态下的背景。
解决:重写ViewGroup的dispatchSetPressed方法,不做任何处理即可。
protected void dispatchSetPressed(boolean pressed) {
}