在Android NativeActivity中管理键盘输入的最佳方法是什么?

时间:2014-05-29 16:16:59

标签: android android-ndk keyboard

我在我的应用程序中使用键盘时出现问题,这是一个纯本机应用程序(基于Android NDK中提供的native-activity sample)。

我有这个Java代码来显示键盘:

mApplicationActivity.runOnUiThread(new Runnable(){
    @Override
    public void run() {

        if(mTextEdit != null)
            mTextEdit.setVisibility(View.GONE);     
        mTextEdit = new EditText(mApplicationActivity);

        InputMethodManager m = (InputMethodManager) mApplicationActivity.getSystemService(Context.INPUT_METHOD_SERVICE);
        mTextEdit.setText(mTextEditValue);
        mEditTextLayoutParams = new FrameLayout.LayoutParams(FrameLayout.LayoutParams.WRAP_CONTENT, FrameLayout.LayoutParams.WRAP_CONTENT);
        mEditTextLayoutParams.gravity = Gravity.TOP;
        mEditTextLayoutParams.setMargins(left, top, right, bottom);
        mTextEdit.setLayoutParams(mEditTextLayoutParams);
        mTextEdit.setVisibility(View.VISIBLE);
        mTextEdit.addTextChangedListener(mTextWatcher);

        mApplicationActivity.addContentView(mTextEdit, mEditTextLayoutParams);

        mTextEdit.bringToFront();
        mTextEdit.setSelection(mTextEdit.getText().length());
        mTextEdit.requestFocus();

        m.showSoftInput(mTextEdit, InputMethodManager.SHOW_FORCED);
    }
});

我使用textWatcher检测输入更改以通知我的C ++代码并更新OpenGL UI。它似乎在我的带有Android 4.4.2的Nexus 4中正常工作,但今天我有一个带有Android 4.2.2的Nexus 4,我无法删除我写的文字。

所以我想知道处理键盘输入的最佳方法是假设:

  • 我使用OpenGL渲染自己的UI,EditText在屏幕外。
  • 使用关键事件是一个坏主意(如下所述:https://code.google.com/p/android/issues/detail?id=42904“它无法正常使用手势输入,语音输入或切换输入,或任何新的创造性输入法开发人员可能会出现在将来。“)

我还会考虑是否可以将Java EditText放在我的OpenGL上,但我无法弄清楚如何做到这一点。

这是textWatcher代码:

TextWatcher mTextWatcher = new TextWatcher() {  
        @Override
        public void onTextChanged(CharSequence s, int start, int before, int count) {
            // Call to C++ code 
            SendChangedText(s.toString());
        }

        @Override
        public void beforeTextChanged(CharSequence s, int start, int count, int after) {

        }

        @Override
        public void afterTextChanged(Editable s) {

        }
    };

1 个答案:

答案 0 :(得分:1)

我还在项目中使用NativeActivity。关键事件方法 -

public boolean dispatchKeyEvent(KeyEvent event) { ... }

仅在开始工作直到一天,在4.4下有一个错误,其中退格(删除)键事件根本没有发送到事件处理程序。因为它似乎是已知的基本安卓键盘的bug。所以我从原始的按键处理转移到隐藏的EditText'解。

隐藏的EditText为您提供了摆脱错误和处理预测输入的方法。为此,您需要实现自己的InputConnectionWrapper(或者它也可以是BaseInputConnection)。在EditText里面覆盖onCreateInputConnection:

@Override
public InputConnection onCreateInputConnection(EditorInfo outAttrs) {

    // We set manual input connection to catch all keyboard interaction
    return new MyInputConnection(super.onCreateInputConnection(outAttrs), true);

}

@Override
public boolean onCheckIsTextEditor() {
    return true;
}

现在我们可以在里面捕获很多输入事件:

class MyInputConnection extends InputConnectionWrapper {

public MyInputConnection(InputConnection target, boolean mutable) {
    super(target, mutable);
}

@Override
public boolean setComposingText(CharSequence text, int newCursorPosition)
{
    Log.d(TAG, "setComposingText " + text);
    return super.setComposingText(text, newCursorPosition);
}

@Override
public boolean commitText(CharSequence text, int newCursorPosition)
{
    Log.d(TAG, "commitText " + text);
    return super.commitText(text, newCursorPosition);
}

@Override
public boolean sendKeyEvent(KeyEvent event) {
    return super.sendKeyEvent(event);
}


@Override
public boolean deleteSurroundingText(int beforeLength, int afterLength) {       
    if (beforeLength == 1 && afterLength == 0) {
            Log.d(TAG, "DELETE!");
    }

    return super.deleteSurroundingText(beforeLength, afterLength);
}

}

有关详细信息,请参阅InputConnectionWrapper类。据我所知,从软件键盘捕获所有事件的唯一方法是覆盖此接口提供的所有方法。