【问题标题】:Custom SoftKeyboard View not displaying properly自定义软键盘视图未正确显示
【发布时间】:2012-09-24 23:27:58
【问题描述】:

我扩展了 Android Sample SoftKeyboard 示例。 这个扩展需要在键盘上方添加两个垂直的 AlphabetLinearLayouts(从 LinearLayout 扩展),除了 LatinKeyBoardView。 LatinKeyboardView 是标准键盘。

当我从布局中删除这两个侧视图时,行为符合预期 - 在 EditText 内部进行选择会拉起软键盘,并且之前屏幕上的所有视图都会向上移动。

通常当键盘纵向弹出时,屏幕上的任何内容都会移到键盘上方,有效地将一些内容推离屏幕,为键盘腾出空间。

我认为因为我有这两个额外的垂直视图作为我的键盘的一部分,所以框架试图向上推送内容并失败,因为键盘视图占用了太多空间。

我正在尝试找出解决此问题的方法。最好的情况是以某种方式让我的垂直视图显示在原始内容之上,除了显示软键盘所需的内容之外没有进一步的位移。

我按如下方式构造我的 KeyboardView:

@Override public View onCreateInputView() {
  RelativeLayout outer = (RelativeLayout) getLayoutInflater().inflate(
        R.layout.input, null);
  // Set up keyboard view.
  mInputView = (LatinKeyboardView) outer.findViewById(R.id.keyboard);
  mInputView.setOnKeyboardActionListener(this);
  mInputView.setKeyboard(mQwertyKeyboard);
  // Maintain reference to APC.
  mAlphabetViewLeft = (AlphabetColumnLayout)outer.findViewById(R.id.alphabet_list_left);
  mAlphabetViewRight = (AlphabetColumnLayout)outer.findViewById(R.id.alphabet_list_right);

  // Set of references to handle touches.
  mAlphabetViewLeft.setTouchResolver(mTouchResolver);
  mAlphabetViewRight.setTouchResolver(mTouchResolver);

  return outer;
}

我的 input.xml 文件如下所示:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
  android:layout_width="match_parent"
  android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res/com.example.android.softkeyboard">

<com.example.android.softkeyboard.AlphabetColumnLayout
    android:id="@+id/alphabet_list_left"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignParentLeft="true"
    android:layout_above="@+id/keyboard"
    android:orientation="vertical"
    app:available_letters="BGHIJKLMNOPUVY"/>

<com.example.android.softkeyboard.AlphabetColumnLayout
    android:id="@+id/alphabet_list_right"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignParentRight="true"
    android:layout_above="@+id/keyboard"
    android:orientation="vertical"
    app:available_letters="ACDEFQRSTWXZ"/>

<com.example.android.softkeyboard.LatinKeyboardView
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/keyboard"
    android:layout_alignParentBottom="true"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"/>

</RelativeLayout>

最后,我使用以下代码设置了 AlphabetColumnLayouts。它的作用是在键盘上方屏幕的每一侧创建一堆字母(我上面提到的两个输入视图)。 AlphabetTextView 是一个普通的 TextView,带有一些额外的东西来帮助我以我想要的方式解决触摸问题。 char[] 字母使用 input.xml 中的 app:available_letters 样式实例化。

public void instantiateViews(char[] letters, int appSize) {
  Context context = mWeakContext.get();
  assertNotNull(context);

  // Set up layout params of parent based on the screen size available,
  // keeping XML-defined params.
  RelativeLayout.LayoutParams lp =
      (RelativeLayout.LayoutParams) getLayoutParams();
  if (lp == null) {
    lp = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT,
        RelativeLayout.LayoutParams.WRAP_CONTENT);
  }
  lp.height = appSize/2;
  Log.e(TAG, "LinearLayout = " + lp.debug(""));
  setLayoutParams(lp);

  // Set up the child TextViews.
  final int nLetters = letters.length;
  for (char c : letters) {
    AlphabetTextView tv = new AlphabetTextView(context, this);
    LinearLayout.LayoutParams tlp = new LinearLayout.LayoutParams(
      LinearLayout.LayoutParams.MATCH_PARENT,
      lp.height/nLetters);
    tv.setLayoutParams(tlp);
    //tv.setGravity(Gravity.CENTER);
    tv.setText(String.valueOf(c));
    tv.setTextSize(12);
    tv.setTypeface(Typeface.DEFAULT_BOLD);

    // Add child to Layout.
    addView(tv);
  }
  setOnTouchListener(this);
}

这里是a link 我发布的 Android 群组问题,并附有一些图片。

【问题讨论】:

  • 你应该发布你的代码。这可能是很多事情的结果......

标签: android view ime


【解决方案1】:

你的描述不是很清楚。您实际上看到了什么是错误的?此外,您所描述的听起来像是您想创建自己的候选人版本?实现onCreateCandidateViews() 不适合您的需求吗?

更新

看了截图,我现在明白你的意思了。

我认为你基本上是在痛苦的道路上。您创建的是KeyboardView,其大小与View 相同,其高度包括TextView 列(不足为奇)。应用程序如何与输入法交互并不取决于输入法,而是取决于应用程序本身。在这种情况下,消息应用程序似乎将其android:windowSoftInputMode 设置为adjustResize(因此它在方向更改后“坐在”您的KeyboardView 之上 - 我不知道为什么它在您输入时不调整大小方法先展示)。

此外,即使您确实设法让底层应用程序正常运行,您也会面临输入法问题可能会从应用程序本身窃取触摸事件(即您的 KeyboardView 仍然是一个位于屏幕底部,不管那里有什么透明度。

从本质上讲,Android 的 IME 框架是为输入法设计的,它是一个单一的根视图,它粘贴在 Dialog 中,并显示在屏幕底部。可能是最近的框架变化已经偏离了这一点;添加了一个新的 Keyboard ctor,它允许客户端指定宽度和高度,而不是仅仅假设 Key 大小百分比是屏幕宽度/高度。

无论如何,虽然它可能会做其他事情,只是 IME 必须执行应用程序所期望的,这是黄金法则,因为如果您的 IME 不与用户的应用程序互操作,那么他们将不会使用它。

【讨论】:

  • 感谢您的回复。我添加了一个指向我的 Google Groups 问题的链接,其中包含 2 个屏幕截图,并充实了问题的描述。
  • 回答您关于 onCreateCandidateViews(...) 的问题。我不认为这会有用,因为我的两个侧栏是静态的 - 任何时候都不需要更新它们。我从他们那里收集触摸事件并用它来消除键盘上的按键触摸的歧义。
  • 非常感谢,这就是我认为正在发生的事情,你让我相信没有办法解决它。我可以通过完全避免使用 IME 服务来解决这个问题,并将两侧的两列视为我的应用程序中文本视图周围的两个视图。我宁愿不必从头开始编写键盘 - 是否可以在不将我的应用程序声明为 IME 服务的情况下使用键盘/键盘视图?我想做的是在我的应用程序中放置一个 KeyboardView,并让 onTouch 覆盖更新 TextView
  • 如您所知,Keyboard/KeyboardView 紧密相连,都用于表示输入法的 UI 端。这样做的一个好处是它避免了每个键都有一个视图。您可能可以使用它们(当然作为指南)来创建某种集成到您的应用程序中并处理触摸事件的键盘,尽管我从未考虑过这样做,因此无法对此提供任何指导。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-01-08
  • 2023-04-05
  • 1970-01-01
  • 2019-01-05
  • 1970-01-01
  • 2020-06-25
  • 2011-12-27
相关资源
最近更新 更多