主要涉及到的类:ViewRootImp,ViewGroup,View,FocusFinder
当事件发生时,最主要是从ViewRootImpl的processKeyEvent开始处理分发。
1.ViewRootImpl
1.连接WindowManager和DecorView的纽带
2.完成view的measure,layout,draw
3.向DecorView分发按键、触摸事件等。
1.先判断是否有按键事件处理
1.若返回true,则打断该方向上的焦点寻找。
2.若返回fasle,则根据指定的方向寻找最近且可获取焦点的view
1.如果mView.findFocus()找到了focused
1.1判断mView的类型,是否为ViewGroup。
1.2判断该focused是否是mView内的view
offsetDescendantRectToMyCoords()该方法判断
2.如果没有找到则调用自身的focusSearch() ===此处后文会展开==
补充:ViewRootImpl中的mView指的是Activity中的DecorView后文中会频繁的对mView进行判断或调用mView的方法。
final class ViewPostImeInputStage extends InputStage {
public ViewPostImeInputStage(InputStage next) {
super(next);
}
@Override
protected int onProcess(QueuedInputEvent q) {
if (q.mEvent instanceof KeyEvent) {
return processKeyEvent(q); //若是按键事件,则走该方法处理按键和焦点
} else {
final int source = q.mEvent.getSource();
if ((source & InputDevice.SOURCE_CLASS_POINTER) != 0) {
return processPointerEvent(q); //若是触摸事件,则走该方法处理
} else if ((source & InputDevice.SOURCE_CLASS_TRACKBALL) != 0) {
return processTrackballEvent(q);
} else {
return processGenericMotionEvent(q);
}
}
}
private int processKeyEvent(QueuedInputEvent q) {
final KeyEvent event = (KeyEvent)q.mEvent;
//首先由dispatchKeyEvent进行分发,如果返回true的,则不再继续。
//未被处理KeyEvent处理,则进入寻找下一个焦点的流程。
if (mView.dispatchKeyEvent(event)) {
//该方法内部首先判断拥有focus的view,是否重写了onKeyDown、onKeyUp方法,事件会交给它优先处理。
//当它返回true时,那么事件不再继续传递。也就是说我们可以通过重写返true来拦截。
return FINISH_HANDLED;
}
if (shouldDropInputEvent(q)) {
return FINISH_NOT_HANDLED;
}
if (event.getAction() == KeyEvent.ACTION_DOWN
&& event.isCtrlPressed()
&& event.getRepeatCount() == 0
&& !KeyEvent.isModifierKey(event.getKeyCode())) {
if (mView.dispatchKeyShortcutEvent(event)) {
return FINISH_HANDLED;
}
if (shouldDropInputEvent(q)) {
return FINISH_NOT_HANDLED;
}
}
//若未被子view拦截,开始处理按键,根据direction进行处理
if (event.getAction() == KeyEvent.ACTION_DOWN) {
int direction = 0;
switch (event.getKeyCode()) {
//根据code设置direction的值...............
}
if (direction != 0) {
//DecorView会一层一层往下调用findFocus方法找到当前获取焦点的View
View focused = mView.findFocus();
if (focused != null) {
========= 1. 展开分析focused.focusSearch() ===========
View v = focused.focusSearch(direction);
if (v != null && v != focused) ;
focused.g