/**
* Returns true if this view has focus itself, or is the ancestor of the
* view that has focus.
*
* @return True if this view has or contains focus, false otherwise.
*/@ViewDebug.ExportedProperty(category = "focus")
publicbooleanhasFocus() {
return (mPrivateFlags & PFLAG_FOCUSED) != 0;
}
View中定义了一个isFocused方法,该方法用于判断该View自身是否已经获取到焦点。
/**
* Returns true if this view has focus
*
* @return True if this view has focus, false otherwise.
*/@ViewDebug.ExportedProperty(category = "focus")
publicbooleanisFocused() {
return (mPrivateFlags & PFLAG_FOCUSED) != 0;
}
if (mFirst) {
// handle first focus requestif (DEBUG_INPUT_RESIZE) Log.v(mTag, "First: mView.hasFocus()="+ mView.hasFocus());
if (mView !=null) {
if (!mView.hasFocus()) {
mView.requestFocus(View.FOCUS_FORWARD);
if (DEBUG_INPUT_RESIZE) Log.v(mTag, "First: requested focused view="+ mView.findFocus());
} else {
if (DEBUG_INPUT_RESIZE) Log.v(mTag, "First: existing focused view="+ mView.findFocus());
}
}
}
handle first focus request意味着这里处理第一次焦点的请求,注意这里的mView其实就是DecorView,也就是位于view tree的最顶层的View。其本质就是一个FrameLayout,当自身或者其内部子View不包含焦点的时候,就会调用requestFocus尝试标记焦点View。我们再来看下ViewGroup中重写的requestFocus:
/**
* {@inheritDoc}
*
* Looks for a view to give focus to respecting the setting specified by
* {@link #getDescendantFocusability()}.
*
* Uses {@link #onRequestFocusInDescendants(int, android.graphics.Rect)} to
* find focus within the children of this group when appropriate.
*
* @see #FOCUS_BEFORE_DESCENDANTS
* @see #FOCUS_AFTER_DESCENDANTS
* @see #FOCUS_BLOCK_DESCENDANTS
* @see #onRequestFocusInDescendants(int, android.graphics.Rect)
*/@OverridepublicbooleanrequestFocus(int direction, Rect previouslyFocusedRect) {
if (DBG) {
System.out.println(this + " ViewGroup.requestFocus direction="
+ direction);
}
int descendantFocusability = getDescendantFocusability();
switch (descendantFocusability) {
case FOCUS_BLOCK_DESCENDANTS:
returnsuper.requestFocus(direction, previouslyFocusedRect);
case FOCUS_BEFORE_DESCENDANTS: {
finalboolean took = super.requestFocus(direction, previouslyFocusedRect);
return took ? took : onRequestFocusInDescendants(direction, previouslyFocusedRect);
}
case FOCUS_AFTER_DESCENDANTS: {
finalboolean took = onRequestFocusInDescendants(direction, previouslyFocusedRect);
return took ? took : super.requestFocus(direction, previouslyFocusedRect);
}
default:
thrownew IllegalStateException("descendant focusability must be "
+ "one of FOCUS_BEFORE_DESCENDANTS, FOCUS_AFTER_DESCENDANTS, FOCUS_BLOCK_DESCENDANTS "
+ "but is " + descendantFocusability);
}
}
一,焦点相关Api说明View中定义了一个方法,用来判断View自身是否获取到焦点或者其内部的子View是否获取到焦点。/** * Returns true if this view has focus itself, or is the ancestor of the * view that has focus. * * @return True if this view has or