4
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Androidで背景タップ時にキーボードを閉じる

Posted at

Androidの文字入力がある画面で表示されたソフトウェアキーボードは、デフォルトではユーザが閉じる操作をしない限り表示され続けます。
EditTextなどの対象のView以外をタップしたときにフォーカスを外してキーボードを非表示にしたい、という要件に対応します。
注: composeは考慮していません

タップイベントをフックする

Activity.dispatchTouchEvent(MotionEvent)を使います。
筆者は執筆時にnavigationを利用していたので、目的のFragmentではなく親のActivityに実装しました

    override fun dispatchTouchEvent(ev: MotionEvent?): Boolean {
        binding.navHostFragment.requestFocus()
        return super.dispatchTouchEvent(ev)
    }

requestFocus()ではフォーカスを移動しています。フォーカスを移動することで、キーボードを非表示にしていい操作なのかどうかを判別しています。逆に言うと、何をしてもキーボードを閉じてもいい場合はrequestFocus()は実装しなくて良いと思います。
フォーカスさせるViewはフォーカス可能である必要があるので、設定を加えます。focusableandroid:focusableInTouchModeが目的の設定です

    <androidx.fragment.app.FragmentContainerView
        android:id="@+id/nav_host_fragment"
        android:name="androidx.navigation.fragment.NavHostFragment"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:focusable="true"
        android:focusableInTouchMode="true"
        app:defaultNavHost="true"
        app:navGraph="@navigation/navigation_graph"
        />

キーボードを閉じる

先程の実装によって実装されたフォーカスの変更をフックして、閉じる処理を書いていきます。
webで調べるとEditTextからフォーカスが外れた時、を起点にしている記事が多く見かけますがそれだとすべてのEditTextに実装を追加する必要があります。

こんな感じ

       binding.editText.setOnFocusChangeListener { view, b ->
            if (!b) {
                val imm = getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
                imm.hideSoftInputFromWindow(view.windowToken, 0)
            }
        }

それでも良いですがフォーカスさせたView自体に実装を加えると、少し楽になります。

       binding.navHostFragment.setOnFocusChangeListener { view, b ->
            if (b) { // 条件を反転させた
                val imm = getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
                imm.hideSoftInputFromWindow(view.windowToken, 0)
            }
        }

制御フローとしては

  1. タップする
  2. Activity(View)でハンドリングする
  3. フォーカスを移動させる
  4. 移動先はキーボード表示不要なViewなので、フォーカスされている場合は閉じる処理を実行する

参考

4
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?