👺
Android|EditTextのキーボード非表示 & focus管理
EditTextって割とリスナーイベント設定してキーボードの表示管理しないといけないなと思い、まとめた次第です。あと、EditTextにfocusあたったままになるので、このfocus管理方法もまとめております。
※本記事はviewBinding、navigationを用いての方法で記載しております。
キーボード非表示
まずはキーボードを非表示にする方法です。
fun showOffKeyboard() {
val imm = requireContext().getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
imm.hideSoftInputFromWindow(binding.root.windowToken, InputMethodManager.HIDE_NOT_ALWAYS)
}
でもって、キーボードを非表示にする時って主に下記の2つかと思いますので、
それぞれのリスナーをご紹介
エンターキー押した時
binding.editText.setOnEditorActionListener { _, i, keyEvent ->
if (i == EditorInfo.IME_ACTION_SEARCH ||
i == EditorInfo.IME_ACTION_DONE ||
keyEvent != null &&
keyEvent.action == KeyEvent.ACTION_DOWN &&
keyEvent.keyCode == KeyEvent.KEYCODE_ENTER) {
if (keyEvent == null || !keyEvent.isShiftPressed) {
showOffKeyboard() // キーボード非表示
return@setOnEditorActionListener true
} else {
return@setOnEditorActionListener false
}
} else {
return@setOnEditorActionListener false
}
}
EditText以外をタップ
ViewをタップしたときにfocusをそのままViewにして解除してあげる
Activityで呼んであげるようにする。
メリットとしてFragmentにEditTextが追加された場合でも特に追記する必要がないこと。
override fun dispatchTouchEvent(ev: MotionEvent?): Boolean {
showOffKeyboard()
return super.dispatchTouchEvent(ev)
}
EditTextのフォーカス管理
EditTextにずっとフォーカスがあたっているので、focusをViewにあててあげることで解決します。
view.requestFocus()
そのためにはまずはfocusをあてるレイアウトにそれぞれ下記を追加して、
focusできるようにしておく必要があるので追加します。
android:focusable="true"
android:focusableInTouchMode="true"
まとめ
最後にキーボードの非表示とフォーカス管理をまとめたコードを記載します。
/** Activity内に記載 **/
// Viewタッチしたときのリスナー
override fun dispatchTouchEvent(ev: MotionEvent?): Boolean {
binding.root.requestFocus()
return super.dispatchTouchEvent(ev)
}
/** Fragmentに記載 **/
// EditTextのフォーカス変更リスナー
binding.editText.setOnFocusChangeListener { v, hasFocus ->
// フォーカスが外れた時に キーボード非表示
if(!hasFocus) {
showOffKeyboard()
}
}
// エンターキーリスナー
binding.editText.setOnEditorActionListener { _, i, keyEvent ->
if (i == EditorInfo.IME_ACTION_SEARCH ||
i == EditorInfo.IME_ACTION_DONE ||
keyEvent != null &&
keyEvent.action == KeyEvent.ACTION_DOWN &&
keyEvent.keyCode == KeyEvent.KEYCODE_ENTER) {
if (keyEvent == null || !keyEvent.isShiftPressed) {
// フォーカスをはずす
binding.root.requestFocus()
return@setOnEditorActionListener true
} else {
return@setOnEditorActionListener false
}
} else {
return@setOnEditorActionListener false
}
}
// キーボード非表示
private fun showOffKeyboard() {
val imm = requireContext().getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
imm.hideSoftInputFromWindow(binding.root.windowToken, InputMethodManager.HIDE_NOT_ALWAYS)
}
Discussion