【问题标题】:Behaviour of imeOptions, imeActionId and imeActionLabelimeOptions、imeActionId 和 imeActionLabel 的行为
【发布时间】:2013-11-14 06:09:09
【问题描述】:

我对 Android 原生开发还很陌生,我正在尝试弄清楚如何自定义 IME 操作按钮。我查看了 Google 文档,但几乎找不到有关预期行为的信息。

offical guide了解到,可以使用属性来配置键盘动作按钮:

  • android:imeOptions 可以将显示在空格键附近的按钮的 text/id 设置为一些预定义的值(例如 actionGo 将键标签设置为 Go 并将 id 设置为2)
  • android:imeActionLabel 设置键盘全屏时在输入区域内显示的按钮的标签,通常是横向模式。可以设置为任何字符串值。
  • android:imeActionId和之前一样,但是设置了传递给回调方法的数字Id

但经过一些经验尝试后,我发现 API 级别 15 和下一个 API 级别之间的行为不同。

我设置了一个简单的 EditText 元素,具有以下属性:

<EditText
        ...
        android:imeOptions="actionGo"
        android:imeActionLabel="Custom"
        android:imeActionId="666"
        android:inputType="text"/>

我已经检查了纵向和横向模式下不同 API 级别的效果。这是结果。

API 级别 15 - 4.0.3

在纵向模式下,键标签是Go,传递给回调方法的操作ID是2,与imeOptions设置相对应。

在横向模式下,键标签/id 是 Go/2 作为纵向模式,而在输入区域显示的按钮是 Custom/666,根据imeActionLabel 和 imeActionId 属性。

API 级别 16、17 和 18 - 4.1.2、4.2.2 和 4.3

在纵向和横向模式下,键和按钮都以自定义标签显示,并绑定到 666 id,忽略 imeOptions 属性。

这种不匹配的行为非常烦人,因为:

  • API 级别 >= 16 时,您无法区分按键按钮和输入区域按钮
  • API 级别 = 15 时,您无法为按键设置任何自定义文本。

您知道如何在 API 15 和 16+ 中获取此信息吗? 或者是否有办法在所有(或至少部分)API 版本中获得一致的行为?

也许我在 IME 设置中遗漏了一些可以证明不同行为的东西......

非常感谢!

【问题讨论】:

    标签: android android-input-method


    【解决方案1】:

    只需在 java 代码中以编程方式调用 .setImeActionLabel() 以将 actionID(再次)设置为您想要的。

    editText.setImeActionLabel(getString(R.string.xxx), EditorInfo.IME_ACTION_GO);
    

    【讨论】:

    • 对我不起作用,标签没有改变,我在“onEditorAction”也得到了不同的 ID
    【解决方案2】:

    实际上是由输入法应用而不是 Android 框架本身来决定如何处理您设置的值。

    Android 框架只是将您设置的值传递给输入法,然后输入法可以选择在键盘上显示哪些按钮或在全屏视图中“提取”EditText。 Android 框架通过两种方式影响EditorInfo:-

    • 它通过EditorInfo.makeCompatible 传递它以确保其中的值在键盘和应用程序的targetApiVersions 之间兼容。目前这只影响一些 InputType 值,而不是编辑器操作,但如果引入新的编辑器操作(或全新的设置),这可能会改变。

    • 它为输入法设置默认行为,包括全屏编辑器的行为。如果输入法选择不覆盖这个默认行为,那么它最终可能会出现在 Android 版本之间不同的行为。许多键盘确实选择设置自己的行为,以在 Android 版本之间保持一致。

    因此,要说某个 EditorInfo 字段对任何给定版本都有一定的影响并不是那么简单,并且无法确保一致的行为,即使在一个 Android 版本上也是如此。您所做的只是为输入法提供提示,选择如何将它们呈现给用户。

    【讨论】:

    • 所以我说得对,这就是为什么尽管我更改了标签,但仍然存在“OK”的原因,并且在“onEditorAction”中收到的 id 与我在 xml 中设置的 id 不同?
    • 我不知道为什么您的应用程序会以特定方式运行。听起来您需要
    • 但是你的第一句话在这里很清楚。在我自己的三星 S7 上,该标签被忽略。在 Nexus 6 模拟器上使用它。
    【解决方案3】:

    如果有人正在为 Android 设计自定义键盘,并且对 Enter 键的标签有问题,您应该执行以下操作。在 Android 自定义键盘示例中,我们在 SoftKeyboard.java 中有以下方法:

    @Override
        public void onStartInput(EditorInfo attribute, boolean restarting)
        {
            super.onStartInput(attribute, restarting);
    .
    . // the implementation
    . 
            mCurKeyboard.setImeOptions(getResources(), attribute.imeOptions);
        }
    

    将最后一行更改为以下行:

    mCurKeyboard.setImeOptions(getResources(), attribute);
    

    现在在 LatinKeyboard.java 中更改 setImeOptions 方法,如下所示:

    void setImeOptions(Resources res, EditorInfo ei)
        {
            if (mEnterKey == null)
            {
                return;
            }
    
            switch (ei.imeOptions & (EditorInfo.IME_MASK_ACTION | EditorInfo.IME_FLAG_NO_ENTER_ACTION))
            {
                case EditorInfo.IME_ACTION_SEND:
                    mEnterKey.iconPreview = null;
                    mEnterKey.icon = null;
                    mEnterKey.label = res.getText(R.string.label_send_key);
                    break;
                case EditorInfo.IME_ACTION_GO:
                    mEnterKey.iconPreview = null;
                    mEnterKey.icon = null;
                    mEnterKey.label = res.getText(R.string.label_go_key);
                    break;
                case EditorInfo.IME_ACTION_NEXT:
                    mEnterKey.iconPreview = null;
                    mEnterKey.icon = null;
                    mEnterKey.label = res.getText(R.string.label_next_key);
                    break;
                case EditorInfo.IME_ACTION_SEARCH:
                    mEnterKey.icon = res.getDrawable(R.drawable.sym_keyboard_search);
                    mEnterKey.label = null;
                    break;
                default:
                    mEnterKey.iconPreview = null;
                    mEnterKey.label = res.getText(R.string.label_enter_key);
                    mEnterKey.icon = null;
                    break;
            }
    
            if (ei.actionLabel != null)
            {
                mEnterKey.iconPreview = null;
                mEnterKey.icon = null;
                mEnterKey.label = ei.actionLabel;
            }
        }
    

    现在您的自定义键盘会根据 imeActionLabel 的 xml 文件中定义的内容显示正确的标签。

    【讨论】:

      【解决方案4】:

      当您开始一个新的 Android 项目时,它为您的问题提供了一个很好的提示。有一个名为LoginActivity 的活动,您可以将其创建为默认登录屏幕。此活动将产生一个EditText,如下所示:

                  <EditText
                          android:id="@+id/password"
                          android:layout_width="match_parent"
                          android:layout_height="wrap_content"
                          android:hint="@string/prompt_password"
                          android:imeActionId="@+id/login"
                          android:imeActionLabel="@string/action_sign_in_short"
                          android:imeOptions="actionUnspecified"
                          android:inputType="textPassword"
                          android:maxLines="1"
                          android:singleLine="true"/>
      

      现在,如果您阅读documentation,就会知道imeOptions 属性允许您为文本字段指定其他操作。比如弹出的键盘右下角有“下一步”之类的动作。使用imeOptions,您可以从Android 提供的预定义列表中选择另一个操作。您可以指定诸如“actionSend”或“actionSearch”之类的内容。

      一旦你这样做了,为了你的活动,你可以使用setOnEditorActionListener事件处理程序来监听那个动作:

          mPasswordView = (EditText) findViewById(R.id.password);
          mPasswordView.setOnEditorActionListener(new TextView.OnEditorActionListener() {
              @Override
              public boolean onEditorAction(TextView textView, int id, KeyEvent keyEvent) {
                  if (id == R.id.login || id == EditorInfo.IME_NULL) {
                      attemptLogin();
                      return true;
                  }
                  return false;
              }
          });
      

      请注意我们如何在此处定位imeActionId。这是在您的 Activity 中定位 EditText 的另一种方法,同时还可以灵活地更改键盘输入上的操作。

      【讨论】:

        猜你喜欢
        • 2016-05-26
        • 2018-10-01
        • 1970-01-01
        • 1970-01-01
        • 2014-05-27
        • 2011-04-22
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多