Android Lollipop软键盘不接受GL表面的按键

时间:2015-01-09 12:22:36

标签: android input opengl-es keyboard

在我工作的当前全屏opengl项目中,我有一些基于GL的图形元素,特别是文本输入字段。为了在此元素具有焦点时输入文本,我显示软键盘(显示正常)。

在5.0之前的Android版本上,谷歌键盘工作正常,发送硬件键盘等关键事件。在Android Lollipop上,一些其他键盘如Swiftkey或免费的黑客键盘仍在使用,但Google键盘已经不存在了。

当在Lollipop上的Google键盘上按键时,键盘本身不会出现视觉反馈,我的应用程序会收到触摸事件,就像键盘未显示一样(但确实如此)。 “硬件”后退键可以正常工作。

应用程序中使用的视图是SurfaceView(它不是TextView)。我已覆盖onCheckIsTextEditor并从InputConnection返回特定onCreateInputConnection,我将inputType设置为TYPE_NULL。 请注意,onCreateInputConnection似乎没有被调用。

此应用程序使用Android级别15兼容性进行编译。

知道什么会阻止键盘接受触摸事件? 我该怎么做才能调试触摸事件流程?

2 个答案:

答案 0 :(得分:1)

我终于找到了解决问题的方法,尽管我并不完全理解它为什么会起作用。此解决方案部分基于Cocos2d-x在Android上的输入。

我创建了一个android EditText(实际上是一个继承EditText的类,我在其中覆盖onKeyUponKeyDown,这是为了跟踪焦点和后退键。

我没有将SurfaceView作为活动的唯一元素,而是创建了一个布局,其背景中包含虚假的编辑文本(但不是全屏),而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,这主要是为了捕获用户输入的文本并将其发送回SurfaceView上基于GL的编辑文本(在我的情况下,当调用afterTextChanged方法时,我将收到的字符转换为路由到我的GL控件的内部keydown / keyup事件。

当需要显示虚拟键盘时(例如当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);
  }
}

答案 1 :(得分:0)

我有完全相同的问题。谷歌键盘没有正确显示,并通过它的按钮传递了触摸输入。

事实证明,Google键盘对于传递到<Style x:Key="blueDataPointStyle" TargetType="{x:Type charting:LineDataPoint}" BasedOn="{StaticResource dataPointStyle}"> <Setter Property="Background" Value="Blue"/> </Style> <Style x:Key="redDataPointStyle" TargetType="{x:Type charting:LineDataPoint}" BasedOn="{StaticResource dataPointStyle}"> <Setter Property="Background" Value="Red"/> </Style> <Style x:Key="greenDataPointStyle" TargetType="{x:Type charting:LineDataPoint}" BasedOn="{StaticResource dataPointStyle}"> <Setter Property="Background" Value="Green"/> </Style> 的{​​{1}}类的默认设置不满意。如果您填写至少private void UserControl_Loaded(object sender, RoutedEventArgs e) { int count = 0; foreach (LineSeries line in chart.Series) { switch (count % 3) { case 0: line.DataPointStyle = Resources["blueDataPointStyle"] as Style; break; case 1: line.DataPointStyle = Resources["redDataPointStyle"] as Style; break; case 2: line.DataPointStyle = Resources["greenDataPointStyle"] as Style; break; } count++; } } 字段并将其余字段保留为默认值,即使您从函数返回EditorInfo,它也会有效。

为了解决这个问题,我已将这些行添加到我的onCreateInputConnection子类中:

imeOptions