android - 在方向变化时维护虚拟键盘的更简洁方法

标签 android kotlin android-softkeyboard android-input-method android-savedstate

我的 XML 中有以下 EditText:

<EditText
  android:id="@+id/searchField"
  android:layout_width="wrap_content"
  android:layout_height="wrap_content"
  android:hint="What do you want to eat?"
  android:imeOptions="actionSearch"
  android:inputType="text"
  android:maxLines="1"
  ... />

在方向更改时,我将记录 EditText、searchField 的聚焦状态。我使用 override fun onSaveInstanceState(...) 记录此状态,如下所示:

override fun onSaveInstanceState(outState: Bundle) {
    super.onSaveInstanceState(outState)
    outState.putBoolean("SEARCH_FOCUSED", searchField.hasFocus())
}

如果 searchField.hasFocus() 等于 true,我希望在设备方向更改时显示虚拟键盘。为此,我在 override fun onRestoreInstaceState(...) 上设置了此选项,如下所示:

override fun onRestoreInstanceState(savedInstanceState: Bundle) {
    super.onRestoreInstanceState(savedInstanceState)
    val imm = getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
    val searchFocused = savedInstanceState.getBoolean("SEARCH_FOCUSED")
    if (searchFocused) {
        searchField.requestFocus()
        searchField.postDelayed({ imm.showSoftInput(searchField,
            SHOW_FORCED)
        }, 200)
    }
}

以上有效

问题#1

但是,上述方式并不理想。我必须设置一个 postDelayed(Runnable, time) 来使虚拟键盘出现,这对我来说似乎不是最好的解决方案。 理想情况,我希望能够简单地执行以下操作。但以下代码的问题是,键盘在方向更改时根本不显示。

override fun onRestoreInstanceState(savedInstanceState: Bundle) {
    super.onRestoreInstanceState(savedInstanceState)
    val imm = getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
    val searchFocused = savedInstanceState.getBoolean("SEARCH_FOCUSED")
    if (searchFocused) {
        searchField.requestFocus()
        imm.showSoftInput(searchField, SHOW_FORCED)
    }
}

问题 #2

此外,请注意我使用了 SHOW_FORCED 而不是 SHOW_IMPLICIT。这真的很糟糕,因为当我点击主页按钮时(Activity 现在是 onStop()),键盘仍然可见。我知道这是由于 SHOW_FORCED 表明键盘必须由用户自己显式隐藏。 理想情况,我想使用SHOW_IMPLICIT。使用 SHOW_IMPLICIT 的问题是键盘不会出现在横向方向上,而是出现在纵向方向上。

所以,我的问题是:

  • 为什么我无法在不使用 postDelayed(...) 来显示虚拟键盘的情况下立即设置 imm.showSoftInput(...) ?我是否缺少使用 showSoftInput 时的其他一些先决步骤?
  • 如何使用 SHOW_IMPLICIT 确保当 Activity 处于后台时自动隐藏键盘 (onPause()/onStop())?

最佳答案

我在其他线程上读到过有关此问题的信息。

这是一个我认为值得尝试的建议:

(这将是 Java 语言,因为我不会说 kotlin,抱歉)

editText.setOnFocusChangeListener(new View.OnFocusChangeListener() {
@Override
public void onFocusChange(View v, boolean hasFocus) {
    if (hasFocus) {
    getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE);
    }else{
    getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN);}
    }
});

这样,只要将焦点授予编辑文本,就应该显示输入法。不过,您可能必须确保您的编辑文本不关注 Activity 创建。让我知道这有效,以及它是否解决了您的两个(或任何)问题。

关于android - 在方向变化时维护虚拟键盘的更简洁方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60586551/

相关文章:

java - 如何使这个位置查找器(GPS)在Android上工作?

android - 如何在Android中使用MPAndroidChart使用两组数据绘制图形

android - '无法访问主线程上的数据库,因为它可能会长时间锁定 UI' 另外,我使用协程访问了房间

java - Maven - 与 JavaME、JavaSE 和 Android 模块共享多模块项目的记录器

java - TypeConverter() 在 Android 中的 Room 的 TypeConverter 错误中具有私有(private)访问权限

android - 当使用带有 EditText 的 AlertDialog.Builder 时,软键盘不会弹出

android - SearchView 可以同时具有语音搜索按钮和键盘语音输入吗?

android - 使用 adb 隐藏软键盘

c# - 在 Xamarin Forms 中将 Android API 目标级别从 11 升级到 12

kotlin - 返回 kotlin 中的标签和 lambda 表达式