【问题标题】:Android Lollipop soft keyboard doesn't accept keypresses with GL surfaceAndroid Lollipop 软键盘不接受带有 GL 表面的按键
【发布时间】:2015-03-07 18:29:03
【问题描述】:

在我从事的当前全屏基于 opengl 的项目中,我有一些基于 GL 的图形元素,特别是文本输入字段。为了在此元素获得焦点时输入文本,我显示了软键盘(看起来很好)。

在 5.0 之前的 android 版本上,Google 键盘工作正常,可以发送与硬件键盘类似的按键事件。在 android Lollipop 上,Swiftkey 或免费的 Hacker 键盘等其他键盘仍在工作,但 Google 键盘不再可用。

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

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

此应用编译时兼容 android 级别 15。

知道什么会阻止键盘接受触摸事件吗? 我应该如何调试触摸事件流?

【问题讨论】:

    标签: android input opengl-es keyboard


    【解决方案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 方法时,我将接收到的字符转换为内部 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);
      }
    }
    

    【讨论】:

      【解决方案2】:

      我遇到了完全相同的问题。 Google 键盘未正确显示,并通过其按钮传递了触摸输入。

      事实证明,Google 键盘对传递给 onCreateInputConnectionEditorInfo 类的默认设置不满意。如果您至少填写 imeOptions 字段并将其余字段保留为默认值,即使您从函数返回 null,它也会起作用。

      为了修复它,我已将这些行添加到我的 SurfaceView 子类中:

      @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);
      }
      

      【讨论】:

      • 我想补充一点,onCreateInputConnection在布局 XML 中将 android:focusableInTouchMode 设置为 true 时调用。
      猜你喜欢
      • 1970-01-01
      • 2015-03-18
      • 2020-03-20
      • 1970-01-01
      • 2019-03-22
      • 2016-01-29
      • 2011-09-22
      • 2011-08-25
      • 1970-01-01
      相关资源
      最近更新 更多