Step 3. View.dispatchKeyEventPreIme
[java] view plaincopyprint?
public class View implements Drawable.Callback, KeyEvent.Callback, AccessibilityEventSource {
......
public boolean dispatchKeyEventPreIme(KeyEvent event) {
return onKeyPreIme(event.getKeyCode(), event);
}
......
}
public class View implements Drawable.Callback, KeyEvent.Callback, AccessibilityEventSource {
......
public boolean dispatchKeyEventPreIme(KeyEvent event) {
return onKeyPreIme(event.getKeyCode(), event);
}
......
}
这个函数定义在文件frameworks/base/core/java/android/view/View.java中。
View类的成员函数dispatchKeyEventPreIme的实现很简单,它只是通过调用另外一个成员函数onKeyPreIme来在输入法之前处理参数event所描述的键盘事件。
Step 4. View.onKeyPreIme
[java] view plaincopyprint?
public class View implements Drawable.Callback, KeyEvent.Callback, AccessibilityEventSource {
......
public boolean onKeyPreIme(int keyCode, KeyEvent event) {
return false;
}
......
}
public class View implements Drawable.Callback, KeyEvent.Callback, AccessibilityEventSource {
......
public boolean onKeyPreIme(int keyCode, KeyEvent event) {
return false;
}
......
}
这个函数定义在文件frameworks/base/core/java/android/view/View.java中。
View类的成员函数onKeyPreIme默认是不会在输入法之前处理参数event所描述的键盘事件的,因此,我们在实现自己的控件的时候,如果需要在输入法之前处理键盘输入,那么就必须重写父类View的成员函数onKeyPreIme。在重写父类View的成员函数onKeyPreIme来处理一个键盘事件的时候,如果不希望这个键盘事件分发给输入法处理,那么就返回一个true值,否则的话,就返回一个false值。
我们假设当前获得焦点的是图1所示的TextView控件,但是由于TextView类没有重写其父类View的成员函数onKeyPreIme,因此,参数event所描述的键盘事件接下来就会继续分发给输入法或者当前激活的窗口处理。
这一步执行完成之后,回到前面的Step 1中,即ViewRoot类的成员函数deliverKeyEvent中,无论接下来是否需要先将一个键盘事件分发给输入法处理,最终都会调用到ViewRoot类的成员函数deliverKeyEventToViewHierarchy来继续将该键盘事件分发给当前激活的窗口处理。
Step 5. ViewRoot.deliverKeyEventToViewHierarchy
[java] view plaincopyprint?
public final class ViewRoot extends Handler implements ViewParent,
View.AttachInfo.Callbacks {
......
private void deliverKeyEventToViewHierarchy(KeyEvent event, boolean sendDone) {
try {
if (mView != null && mAdded) {
final int action = event.getAction();
boolean isDown = (action == KeyEvent.ACTION_DOWN);
......
boolean keyHandled = mView.dispatchKeyEvent(event);
if (!keyHandled && isDown) {
int direction = 0;
switch (event.getKeyCode()) {
case KeyEvent.KEYCODE_DPAD_LEFT:
direction = View.FOCUS_LEFT;
break;
case KeyEvent.KEYCODE_DPAD_RIGHT:
direction = View.FOCUS_RIGHT;
break;
case KeyEvent.KEYCODE_DPAD_UP:
direction = View.FOCUS_UP;
break;
case KeyEvent.KEYCODE_DPAD_DOWN:
direction = View.FOCUS_DOWN;
break;
}
if (direction != 0) {
View focused = mView != null ? mView.findFocus() : null;
if (focused != null) {
View v = focused.focusSearch(direction);
......
if (v != null && v != focused) {
......
focusPassed = v.requestFocus(direction, mTempRect);
}
......
}
}
}
}
} finally {
if (sendDone) {
finishInputEvent();
}
......
}
}
......
}
public final class ViewRoot extends Handler implements ViewParent,
View.AttachInfo.Callbacks {
......
private void deliverKeyEventToViewHierarchy(KeyEvent event, boolean sendDone) {
try {
if (mView != null && mAdded) {
final int action = event.getAction();
boolean isDown = (action == KeyEvent.ACTION_DOWN);
......
boolean keyHandled = mView.dispatchKeyEvent(event);
if (!keyHandled && isDown) {
int direction = 0;
switch (event.getKeyCode()) {
原文转自:http://blog.csdn.net/luoshengyang/article/details/8636153