您的位置:首页 > 移动开发 > Android开发

Android 从输入法 到 EditText 研究

2016-01-15 18:41 531 查看
首先看一个 View 的一个方法:



View 没有实现,直接返回 null,

再看 TextView 的实现,

@Override
public InputConnection onCreateInputConnection(EditorInfo outAttrs) {
if (onCheckIsTextEditor() && isEnabled()) {
...
if (mText instanceof Editable) {
InputConnection ic = new EditableInputConnection(this);
outAttrs.initialSelStart = getSelectionStart();
outAttrs.initialSelEnd = getSelectionEnd();
outAttrs.initialCapsMode = ic.getCursorCapsMode(getInputType());
return ic;
}
...
使用了 EditableInputConnection

现在要知道,这个方法何时被调用?

首先我们是点击了 EditText 系统随机呼出输入法,那么好,我们看 TextView 的 onTouchEvent 方法

@Override
public boolean onTouchEvent(MotionEvent event) {
...
if (touchIsFinished && (isTextEditable() || textIsSelectable)) {
// Show the IME, except when selecting in read-only text.
final InputMethodManager imm = InputMethodManager.peekInstance();
viewClicked(imm);
if (!textIsSelectable && mEditor.mShowSoftInputOnFocus) {
handled |= imm != null && imm.showSoftInput(this, 0);
}<span style="font-family: Arial, Helvetica, sans-serif;"> </span>
这里调用了 imm.showSoftInput 弹出输入法,

但是我们还得找到 TextView 与输入法建立链接的地方,我们查找 InputMethodManager 找到了一处调用,view.onCreateInputConnection 方法:

public void restartInput(View view) {

...

boolean startInputInner(IBinder windowGainingFocus, int controlFlags, int softInputMode,
int windowFlags) {
...
// Okay we are now ready to call into the served view and have it
// do its stuff.
// Life is good: let's hook everything up!
EditorInfo tba = new EditorInfo();
tba.packageName = view.getContext().getPackageName();
tba.fieldId = view.getId();
InputConnection ic = view.onCreateInputConnection(tba);
if (DEBUG) Log.v(TAG, "Starting input: tba=" + tba + " ic=" + ic);

...到这一步似乎 TextView 就与输入法建立起了连接,不过还有很重要的一点是,要弹出输入法首先 EditText 必须获取焦点,正是获取焦点的时候,与输入法进行了关键一步的交流,这个实现在 View:
protected void onFocusChanged(boolean gainFocus, int direction, Rect previouslyFocusedRect) {
...
InputMethodManager imm = InputMethodManager.peekInstance();
if (!gainFocus) {
if (isPressed()) {
setPressed(false);
}
if (imm != null && mAttachInfo != null
&& mAttachInfo.mHasWindowFocus) {
imm.focusOut(this);
}
onFocusLost();
} else if (imm != null && mAttachInfo != null
&& mAttachInfo.mHasWindowFocus) {
imm.focusIn(this);
}
...
调用了 InputMethodManager 的 focusIn 告知输入法当前接受输入的 View,你如果只通过前面几个方法去看,根本不知道 InputMethodManager 何时确定了 View 对象,

然后,输入法与接收客户端进行交互是通过 InputConnection 进行的

public interface InputConnection {
public boolean deleteSurroundingText(int beforeLength, int afterLength); //删除输入的字符
public boolean commitText(CharSequence text, int newCursorPosition); //输入字符
public boolean sendKeyEvent(KeyEvent event); //注入按键
}当你在输入的时候,输入法会调用以上3个方法(夸进程)

具体如何调用不解释,本篇的重点在理清联系,

除了 EditText ,WebView 也能弹出输入法,WebView 我是比较好奇的,因为他只是一个 ViewGroup

欲知详情请移步至此:点击打开链接
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  android imm