Android ViewGroup.setDescendantFocusability函数介绍
在ViewGrup中定义的,是否阻止子View的获取焦点的能力:
三个参数含义:
FOCUS_BEFORE_DESCENDANTS
ViewGroup本身相对焦点进行处理,如果沒有处理则分发给child View进行处理
FOCUS_AFTER_DESCENDANTS
先分发给Child View进行处理,如果所有的Child View都沒有处理,則自己再处理
FOCUS_BLOCK_DESCENDANTS
ViewGroup本身进行处理,不管是否处理成功,都不会分发给ChildView进行处理
源代码的实现:
ViewGroup本身相对焦点进行处理,如果沒有处理则分发给child View进行处理
FOCUS_AFTER_DESCENDANTS
先分发给Child View进行处理,如果所有的Child View都沒有处理,則自己再处理
FOCUS_BLOCK_DESCENDANTS
ViewGroup本身进行处理,不管是否处理成功,都不会分发给ChildView进行处理
源代码的实现:
public void setDescendantFocusability(int focusability) {
switch (focusability) {
case FOCUS_BEFORE_DESCENDANTS:
case FOCUS_AFTER_DESCENDANTS:
case FOCUS_BLOCK_DESCENDANTS:
break;
default:
throw new IllegalArgumentException("must be one of FOCUS_BEFORE_DESCENDANTS, "
+ "FOCUS_AFTER_DESCENDANTS, FOCUS_BLOCK_DESCENDANTS");
}
mGroupFlags &= ~FLAG_MASK_FOCUSABILITY;
mGroupFlags |= (focusability & FLAG_MASK_FOCUSABILITY);
}
可以看到,只有这三个常量可以设置,不是这三个常量会抛出异常的。
设置后,会在requestFocus(int direction, Rect previouslyFocusedRect) 方法里根据设置进行相应的处理。
@Override
public boolean requestFocus(int direction, Rect previouslyFocusedRect) {
if (DBG) {
System.out.println(this + " ViewGroup.requestFocus direction="
+ direction);
}
int descendantFocusability = getDescendantFocusability();
switch (descendantFocusability) {
case FOCUS_BLOCK_DESCENDANTS:
return super.requestFocus(direction, previouslyFocusedRect);
case FOCUS_BEFORE_DESCENDANTS: {
final boolean took = super.requestFocus(direction, previouslyFocusedRect);
return took ? took : onRequestFocusInDescendants(direction, previouslyFocusedRect);
}
case FOCUS_AFTER_DESCENDANTS: {
final boolean took = onRequestFocusInDescendants(direction, previouslyFocusedRect);
return took ? took : super.requestFocus(direction, previouslyFocusedRect);
}
default:
throw new IllegalStateException("descendant focusability must be "
+ "one of FOCUS_BEFORE_DESCENDANTS, FOCUS_AFTER_DESCENDANTS, FOCUS_BLOCK_DESCENDANTS "
+ "but is " + descendantFocusability);
}
}
由上面的代码可以看出来:
super.requestFocus(direction, previouslyFocusedRect);调用父View获取焦点
onRequestFocusInDescendants(direction, previouslyFocusedRect);子view获取焦点