android 输入法/软键盘调用浅谈I--输入法解析

最近在android NDK开发遇到了一个麻烦问题:在底层通过opengl绘制输入界面,但没办法调用输入法(IME),只能往上调用,通过jni通知java层调用输入法。

而对java层的需求就是只弹出输入法,把输入法键盘的按键事件和输入内容直接往底层传递。看似简单的需求,却让我瞎转了几天。

这里把我碰到的问题和解决方法进行总结。

1.调用输入法的方法

InputMethodManager input = (InputMethodManager)mApp.getSystemService(Context.INPUT_METHOD_SERVICE);
input.toggleSoftInput(InputMethodManager.SHOW_FORCED, InputMethodManager.HIDE_NOT_ALWAYS);

input.toggleSoftInput()如果输入法已经打开则隐藏它,如果是隐藏的则显示它。也可直接调用input的show()或者hide()方法直接显示或隐藏。

注:测试结果显示,系统输入法始终处于开启状态,只能隐藏它,不能关闭。

2.必须为输入法提供一个View或者EditText对象用于接收输入内容

在View或者EditText中调用Input.toggleSoftInput()方法,或者Input.showSoftInput(view, flags)把View或者EditText作为参数传递进去来开启软键盘,输入法会把输入内容传递到指定的对象中。

EditText可以通过getText()直接获取输入内容;

View则需要实现以下方法

    public InputConnection onCreateInputConnection(EditorInfo outAttrs) {
        return new MyInputConnection(this, false); 
    }
并创建继承BaseInputConnection的类

    class MyInputConnection extends BaseInputConnection{
        public MyInputConnection(View targetView, boolean fullEditor) { 
            super(targetView, fullEditor);
        }
        
        public boolean commitText(CharSequence text, int newCursorPosition) {
            Log.i("ime", "input text:" + text);
            return true; 
        }
        
        public boolean sendKeyEvent(KeyEvent event) {
        	Log.i("ime", "sendKeyEvent()" + event.getKeyCode());

        	return true;
        }
    }


通过InputConnection建立于输入的联系,一旦有输入内容输入法会调用commText把内容传递进来;

其中还有另外一个重要的方法是sendKeyEvent()。点击软键盘的enter和backspace按键事件并没有传递到commText,而是将事件传递到sendKeyEvent(),通过这个方法可以自定义地处理该事件。

3.软键盘样式、属性设置

EditText API中有许多方法可直接调用来设置软件盘的属性,详细见android api文档,这里不再赘述。View则需要在OnCreateInputConnection(EditorInfo outAttrs)方法,通过outAttrs属性进行设置。

    public InputConnection onCreateInputConnection(EditorInfo outAttrs) {
    	outAttrs.imeOptions = EditorInfo.IME_FLAG_NO_EXTRACT_UI;
//    	outAttrs.inputType = EditorInfo.TYPE_TEXT_VARIATION_PASSWORD;
//    	outAttrs.imeOptions = EditorInfo.IME_ACTION_DONE;
        return new MyInputConnection(this, false); 
    }

软件盘最主要的样式是全屏模式和非全屏模式;在竖屏的情况下没有全屏模式,而在横屏的情况下(尤其是游戏开发)这两种模式都用得比较多。

值得注意的是,在横屏情况下通过View调用输入法,如果是非全屏模式需要设置outAttrs.imeOptions = EditorInfo.IME_FLAG_NO_EXTRACT_UI,否则会出现软键盘没有候选栏的情况,导致无法输入中文,具体原因尚不清楚,如果有了解的朋友还请多指教。



/* TODO 持续更新 */

你可能感兴趣的:(Android)