在 View
的源码里面有一个方法名为: onCreateInputConnection
, 通过该方法可使自定义 view 连接 inputMethod, 可以接受输入信息。该方法的解释如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 /** * Create a new InputConnection for an InputMethod to interact * with the view. The default implementation returns null, since it doesn't * support input methods. You can override this to implement such support. * This is only needed for views that take focus and text input. * * <p>When implementing this, you probably also want to implement * {@link #onCheckIsTextEditor()} to indicate you will return a * non-null InputConnection.</p> * * <p>Also, take good care to fill in the {@link android.view.inputmethod.EditorInfo} * object correctly and in its entirety, so that the connected IME can rely * on its values. For example, {@link android.view.inputmethod.EditorInfo#initialSelStart} * and {@link android.view.inputmethod.EditorInfo#initialSelEnd} members * must be filled in with the correct cursor position for IMEs to work correctly * with your application.</p> * * @param outAttrs Fill in with attribute information about the connection. */ public InputConnection onCreateInputConnection(EditorInfo outAttrs) { return null; }
onCreateInputConnection 方法连接了 view 和 inputMethod,通过创建一个 InputConnection 来接受输入法的信息。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 /** * Created by hanks on 2017/2/16. */ public class KInputConnection extends BaseInputConnection { public KInputConnection(View targetView, boolean fullEditor) { super(targetView, fullEditor); } // 输入法的按键信息 @Override public boolean sendKeyEvent(KeyEvent event) { switch (event.getKeyCode()) { case KeyEvent.KEYCODE_DEL: if (event.getAction()== KeyEvent.ACTION_UP && onCommitTextListener != null) { onCommitTextListener.onDeleteText(); } break; } return super.sendKeyEvent(event); } // 输入法提交了一个 text @Override public boolean commitText(CharSequence text, int newCursorPosition) { if (onCommitTextListener != null) { onCommitTextListener.commitText(text, newCursorPosition); } return true; } private OnCommitTextListener onCommitTextListener; public void setOnCommitTextListener(OnCommitTextListener onCommitTextListener) { this.onCommitTextListener = onCommitTextListener; } public interface OnCommitTextListener { boolean commitText(CharSequence text, int newCursorPosition); void onDeleteText(); } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 /** * 支持输入法的 view * Created by hanks on 2017/2/16. */ public class KInputView extends View { private StringBuilder content = new StringBuilder(); private KInputConnection inputConnection; private TextPaint paint; private InputMethodManager inputMethodManager; public KInputView(Context context) { this(context, null); } public KInputView(Context context, AttributeSet attrs) { super(context, attrs); init(); } private void init() { // 设置可以接受到焦点 this.setFocusable(true); this.setFocusableInTouchMode(true); // 获取 InputMethodManager inputMethodManager = (InputMethodManager) getContext().getSystemService(Context.INPUT_METHOD_SERVICE); paint = new TextPaint(Paint.ANTI_ALIAS_FLAG); paint.setColor(Color.BLUE); float textSize = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, 14, getResources().getDisplayMetrics()); paint.setTextSize(textSize); setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { // 弹出、关闭输入法 inputMethodManager.toggleSoftInput(0, InputMethodManager.HIDE_NOT_ALWAYS); } }); } @Override public InputConnection onCreateInputConnection(EditorInfo editorInfo) { return getInputConnection(editorInfo); } @Override protected void onDraw(Canvas canvas) { // 使用 StaticLayout 来 draw new StaticLayout(content, paint, getWidth(), Layout.Alignment.ALIGN_NORMAL, 1.5f, 0, false).draw(canvas); } private InputConnection getInputConnection(EditorInfo editorInfo) { if (inputConnection != null) { return inputConnection; } inputConnection = new KInputConnection(this, false); inputConnection.setOnCommitTextListener(new KInputConnection.OnCommitTextListener() { @Override public boolean commitText(CharSequence text, int newCursorPosition) { content.append(text); invalidate(); return false; } @Override public void onDeleteText() { if (content.length() <= 0) { return; } content.deleteCharAt(content.length() - 1); invalidate(); } }); return inputConnection; } }
效果图