在方向更改时维护虚拟键盘的更简洁方法

Cleaner way to maintain virtual keyboard on orientation change

我的 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 表明键盘必须由用户 him/herself 显式隐藏。 理想,我想用SHOW_IMPLICIT。使用 SHOW_IMPLICIT 的问题是键盘不会出现在横向上,但会出现在纵向上。

所以,我的问题是:

我在其他线程上读到了这个问题。

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

(这将在 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 创建。让我知道它有效,如果它解决了您的两个(或任何)问题。