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