Более чистый способ поддерживать виртуальную клавиатуру при изменении ориентации - PullRequest
1 голос
/ 08 марта 2020

У меня есть следующий EditText в моем XML:

<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 состоит в том, что клавиатура не отображается в альбомной ориентации, но появляется в портретной ориентации.

Итак, мои вопросы:

  • Почему не могу Я сразу установил imm.showSoftInput(...) без использования postDelayed(...) для виртуальной клавиатуры, чтобы показать? Я пропускаю некоторые другие обязательные шаги при использовании showSoftInput?
  • Как я могу использовать SHOW_IMPLICIT, чтобы убедиться, что клавиатура автоматически скрыта, когда действие находится в фоновом режиме (onPause() / onStop() )?

1 Ответ

0 голосов
/ 20 апреля 2020

Я читал об этой проблеме в других темах.

Вот предложение, которое, я думаю, стоит попробовать:

(это будет в 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);}
    }
});

таким образом, метод ввода должен отображаться всякий раз, когда фокус предоставляется тексту редактирования. вам, возможно, придется убедиться, что ваш текст редактирования не сфокусирован на создании активности. дайте мне знать, что это работает, и если это решает обе (или любые) ваши проблемы.

...