Android Lollipop 软键盘不接受 GL 表面的按键
Android Lollipop soft keyboard doesn't accept keypresses with GL surface
在我当前从事的基于全屏 opengl 的项目中,我有一些基于 GL 的图形元素,尤其是文本输入字段。为了在这个元素有焦点时输入文本,我显示了软键盘(看起来很好)。
在 5.0 之前的 android 版本中,Google 键盘工作正常,可以像硬件键盘一样发送按键事件。在 android Lollipop 上,其他一些键盘(如 Swiftkey 或免费的 Hacker's 键盘)仍在使用,但 Google 键盘不再可用。
当按下 Lollipop 上 Google 键盘上的某个键时,键盘本身没有视觉反馈出现,我的应用程序接收到触摸事件,就好像键盘没有显示一样(但确实如此)。 'hardware' 后退键工作正常。
应用中使用的视图是 SurfaceView(不是 TextView)。我已经从 onCreateInputConnection
覆盖 onCheckIsTextEditor
和 return 一个特定的 InputConnection
,我将 inputType
设置为 TYPE_NULL
。
请注意 onCreateInputConnection
似乎没有被调用。
此应用编译时具有 android 级别 15 兼容性。
知道什么会阻止键盘接受触摸事件吗?
我应该如何调试触摸事件流程?
我终于找到了解决我的问题的方法,尽管我并不真正理解它为什么有效。此解决方案部分基于 Cocos2d-x 对 Android.
上的输入所做的操作
我创建了一个 android EditText
(实际上是一个 class 而不是继承 EditText
,我在其中覆盖了 onKeyUp
和 onKeyDown
,这是跟踪焦点和返回键)。
我没有让 SurfaceView
成为 activity 的唯一元素,而是创建了一个在背景中包含假编辑文本(但不是全屏)的布局,并且 SurfaceView
在上面:
private FrameLayout setupView(View androidView)
{
ViewGroup.LayoutParams framelayout_params = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
frameLayout = new FrameLayout(this);
getFrameLayout().setLayoutParams(framelayout_params);
ViewGroup.LayoutParams edittext_layout_params = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
edittext = new FakeEditText(this);
edittext.setLayoutParams(edittext_layout_params);
// make sure this edit text is not fullscreen
edittext.setImeOptions(EditorInfo.IME_FLAG_NO_FULLSCREEN | EditorInfo.IME_FLAG_NO_EXTRACT_UI);
// ...add to FrameLayout
frameLayout.addView(edittext);
frameLayout.addView(androidView);
return frameLayout;
}
我还添加了一个TextWatcher
链接到假的编辑文本,这主要是为了捕获用户输入的文本并将其发送回我在[=16=上的基于GL的编辑文本](在我的例子中,当调用 afterTextChanged
方法时,我将接收到的字符转换为内部 keydown/keyup 事件,这些事件被路由到我的 GL 控件)。
当需要显示虚拟键盘时(例如当GL文本字段有焦点时),我从GL文本字段内容中设置假的编辑文本内容,并将这个TextWatcher
附加到假的编辑文本,并将虚拟键盘附加到 android 假编辑文本。
// Control is the base class of my GL controls
private void uiShowVirtualKeyboard(Control control)
{
if (fakeEdit.requestFocus()) {
// textWrapper is our TextWatcher
fakeEdit.removeTextChangedListener(textWrapper);
fakeEdit.setText("");
// get the text from the GL Text entry
final String text = control.getTextContent();
// and make sure it's in the android EditText at start
fakeEdit.append(text);
// listen to user changes
fakeEdit.addTextChangedListener(textWrapper);
// show the virtual keyboard
InputMethodManager imm = (InputMethodManager) fAndroidActivity.getSystemService(Context.INPUT_METHOD_SERVICE);
imm.showSoftInput(fakeEdit, InputMethodManager.SHOW_FORCED);
}
}
我遇到了完全相同的问题。 Google 键盘没有正确显示并通过它的按钮传递触摸输入。
事实证明,Google 键盘不满意 EditorInfo
class 传递给 onCreateInputConnection
的默认设置。如果您至少填写 imeOptions
字段并将其余部分保留为默认值,即使您从函数 return null
为了修复它,我将这些行添加到我的 SurfaceView
subclass:
@Override
public InputConnection onCreateInputConnection(EditorInfo outAttrs) {
outAttrs.inputType = InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS | InputType.TYPE_TEXT_VARIATION_SHORT_MESSAGE | InputType.TYPE_CLASS_TEXT;
outAttrs.imeOptions = EditorInfo.IME_FLAG_NO_EXTRACT_UI | EditorInfo.IME_FLAG_NO_FULLSCREEN;
return super.onCreateInputConnection(outAttrs);
}
在我当前从事的基于全屏 opengl 的项目中,我有一些基于 GL 的图形元素,尤其是文本输入字段。为了在这个元素有焦点时输入文本,我显示了软键盘(看起来很好)。
在 5.0 之前的 android 版本中,Google 键盘工作正常,可以像硬件键盘一样发送按键事件。在 android Lollipop 上,其他一些键盘(如 Swiftkey 或免费的 Hacker's 键盘)仍在使用,但 Google 键盘不再可用。
当按下 Lollipop 上 Google 键盘上的某个键时,键盘本身没有视觉反馈出现,我的应用程序接收到触摸事件,就好像键盘没有显示一样(但确实如此)。 'hardware' 后退键工作正常。
应用中使用的视图是 SurfaceView(不是 TextView)。我已经从 onCreateInputConnection
覆盖 onCheckIsTextEditor
和 return 一个特定的 InputConnection
,我将 inputType
设置为 TYPE_NULL
。
请注意 onCreateInputConnection
似乎没有被调用。
此应用编译时具有 android 级别 15 兼容性。
知道什么会阻止键盘接受触摸事件吗? 我应该如何调试触摸事件流程?
我终于找到了解决我的问题的方法,尽管我并不真正理解它为什么有效。此解决方案部分基于 Cocos2d-x 对 Android.
上的输入所做的操作我创建了一个 android EditText
(实际上是一个 class 而不是继承 EditText
,我在其中覆盖了 onKeyUp
和 onKeyDown
,这是跟踪焦点和返回键)。
我没有让 SurfaceView
成为 activity 的唯一元素,而是创建了一个在背景中包含假编辑文本(但不是全屏)的布局,并且 SurfaceView
在上面:
private FrameLayout setupView(View androidView)
{
ViewGroup.LayoutParams framelayout_params = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
frameLayout = new FrameLayout(this);
getFrameLayout().setLayoutParams(framelayout_params);
ViewGroup.LayoutParams edittext_layout_params = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
edittext = new FakeEditText(this);
edittext.setLayoutParams(edittext_layout_params);
// make sure this edit text is not fullscreen
edittext.setImeOptions(EditorInfo.IME_FLAG_NO_FULLSCREEN | EditorInfo.IME_FLAG_NO_EXTRACT_UI);
// ...add to FrameLayout
frameLayout.addView(edittext);
frameLayout.addView(androidView);
return frameLayout;
}
我还添加了一个TextWatcher
链接到假的编辑文本,这主要是为了捕获用户输入的文本并将其发送回我在[=16=上的基于GL的编辑文本](在我的例子中,当调用 afterTextChanged
方法时,我将接收到的字符转换为内部 keydown/keyup 事件,这些事件被路由到我的 GL 控件)。
当需要显示虚拟键盘时(例如当GL文本字段有焦点时),我从GL文本字段内容中设置假的编辑文本内容,并将这个TextWatcher
附加到假的编辑文本,并将虚拟键盘附加到 android 假编辑文本。
// Control is the base class of my GL controls
private void uiShowVirtualKeyboard(Control control)
{
if (fakeEdit.requestFocus()) {
// textWrapper is our TextWatcher
fakeEdit.removeTextChangedListener(textWrapper);
fakeEdit.setText("");
// get the text from the GL Text entry
final String text = control.getTextContent();
// and make sure it's in the android EditText at start
fakeEdit.append(text);
// listen to user changes
fakeEdit.addTextChangedListener(textWrapper);
// show the virtual keyboard
InputMethodManager imm = (InputMethodManager) fAndroidActivity.getSystemService(Context.INPUT_METHOD_SERVICE);
imm.showSoftInput(fakeEdit, InputMethodManager.SHOW_FORCED);
}
}
我遇到了完全相同的问题。 Google 键盘没有正确显示并通过它的按钮传递触摸输入。
事实证明,Google 键盘不满意 EditorInfo
class 传递给 onCreateInputConnection
的默认设置。如果您至少填写 imeOptions
字段并将其余部分保留为默认值,即使您从函数 return null
为了修复它,我将这些行添加到我的 SurfaceView
subclass:
@Override
public InputConnection onCreateInputConnection(EditorInfo outAttrs) {
outAttrs.inputType = InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS | InputType.TYPE_TEXT_VARIATION_SHORT_MESSAGE | InputType.TYPE_CLASS_TEXT;
outAttrs.imeOptions = EditorInfo.IME_FLAG_NO_EXTRACT_UI | EditorInfo.IME_FLAG_NO_FULLSCREEN;
return super.onCreateInputConnection(outAttrs);
}