問題の内容
NavigationComponentを使ってFragment→Fragmentに遷移後、EditTextにrequestFocus()
していてもIMEが即座に表示されない問題に遭遇しました。
cursorはEditTextに表示されているので、focusが当たっていないわけではなさそうです。
新しいActivityをstartさせてFragmentを表示させれば問題なくfocusされてIMEも表示されるので、NavigationComponentに何か問題がありそうです。
同じような問題を抱えている方がいらっしゃいました→Link
(回答なしで悲しい)
調査
まず以下のようなコードで解消できるか試しました(focusが当たっていたらshowSoftInput
でIMEを表示、外れたらhideSoftInputFromWindow
でIMEを隠す)
val binding: HogeActivityBinding = DataBindingUtil.setContentView(this, R.layout.hoge_activity)
binding.editText.apply {
setOnFocusChangeListener { v, hasFocus ->
val imm = root.context.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
if (hasFocus) {
imm. showSoftInput(v, 0)
} else {
imm.hideSoftInputFromWindow(v.windowToken, 0)
}
}
}
こちらだと、遷移後すぐにIMEが出ることはありませんでした。
EditText外をタッチすればIMEが消えたので、hideSoftInputFromWindow
は問題なく効いているようです。
次はtoggleSoftInput
を使います。
val binding: HogeActivityBinding = DataBindingUtil.setContentView(this, R.layout.hoge_activity)
binding.editText.apply {
setOnFocusChangeListener { v, hasFocus ->
val imm = binding.root.context.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
if (hasFocus) {
imm.toggleSoftInput(InputMethodManager.SHOW_FORCED, InputMethodManager.HIDE_IMPLICIT_ONLY)
} else {
imm.hideSoftInputFromWindow(v.windowToken, 0)
}
}
}
こちらは遷移直後にIME表示されました。
上手くいったと安心したのも束の間、今度はホームボタンを押したらIMEが残り続ける別の問題が発生。。。
解決
第一引数をInputMethodManager.SHOW_IMPLICIT
にすることで解決できました。
val binding: HogeActivityBinding = DataBindingUtil.setContentView(this, R.layout.hoge_activity)
binding.editText.apply {
setOnFocusChangeListener { v, hasFocus ->
val imm = binding.root.context.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
if (hasFocus) {
imm.toggleSoftInput(InputMethodManager.SHOW_IMPLICIT, InputMethodManager.HIDE_IMPLICIT_ONLY)
} else {
imm.hideSoftInputFromWindow(v.windowToken, 0)
}
}
}
終わりに
根本原因の追及まではできませんでしたが、とりあえず回避策は見つかってよかったです。
NavigationComponent便利なのですがこういう細かいところでつまづきがあるので、今後直っていって欲しいですね。