キーボードを非表示する方法 | Kotlin




キーボードを非表示にする方法。
(ついでにキーボード表示する方法も)

何度も同じこと調べてしまう人間なので、自分のために事細かに補足しまくっています。
ので、ダラダラ長い記事です。

初心者による初心者の自分の為のメモ！！(初投稿)



##1.背景タップでキーボード非表示にする方法

イメージ
・EditText(氏名とTELのとこ)をタップするとキーボードが表示される
・背景(linearLayoutにした)をタップするとキーボードが閉じる

![keybord1.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2499099/5e1651d1-5bb2-c760-061c-9e721b46fcac.gif)

```kotlin:MainActivity
class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
    }
          //画面がタッチされた時に反応するやつ
    override fun onTouchEvent(event: MotionEvent?): Boolean {
        // InputMethodManagerを取得
        val inputMethodManager =
            getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
        //背景のlinearLayoutを取得
        val linearLayout = findViewById<LinearLayout>(R.id.linear_layout)
        // キーボードを閉じる
        inputMethodManager.hideSoftInputFromWindow(
            linearLayout.windowToken,
            InputMethodManager.HIDE_NOT_ALWAYS
        )

        return false
    }
}
```

レイアウトは適当だけど(キーボードもnumber表示とかになってない)、
こんな感じ。

```Kotlin:activity.main
<LinearLayout
    android:id="@+id/linear_layout"
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    tools:context=".MainActivity"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:focusableInTouchMode="true"
    android:orientation="vertical">

    <EditText
        android:id="@+id/ed_name"
        android:layout_width="200dp"
        android:layout_height="wrap_content"
        android:layout_marginTop="100dp"
        android:layout_marginLeft="100dp"
        android:hint="氏名" />

    <EditText
        android:id="@+id/ed_tel"
        android:layout_width="200dp"
        android:layout_height="wrap_content"
        android:layout_marginTop="44dp"
        android:layout_marginLeft="100dp"
        android:hint="TEL"/>

</LinearLayout>
```


`onTouchEvent `
 画面がタッチされたときに呼ばれる方。今回は"タッチされたこと"だけを目的に使っているけど、どんな操作されたか(スクロールとか)もMotionEventで把握できるらしい。
`InputMethodManager`
入力方式を明確にしたい時に使うみたい。入力方式を明確っていうのは、EditTextはタップすると通常キーボードが表示されるようになってるけどそうゆうのを自分で制御できるよ、ってことだと思う。
getSystemServiceのINPUT_METHOD_SERVICEというactivityの入力関係に携わる方をInputMethodManager型にキャストして取得しているイメージ。
`HIDE_NOT_ALWAYS `
元々キーボードが表示されている場合を除いて、通常はキーボードを非表示にする。


結局やっていることは、
「通常タップするとキーボードが表示するもの(EditText)にフォーカスが当たっていなければ、キーボードを非表示にする。」
と理解している。


上記の実装は背景としてLayout(linearLayout)を明示する考え方。

だけど、
背景としてLayoutは指定せず、現在のフォーカスがView(EditText)別の何か(キーボード表示されないLayoutやView)なのかって考え方をするなら、
上記のコードのLayout取得の箇所消して、代わりにこちらを入れても良いみたい。

```
val focusView = currentFocus ?: return false
```
`currentFocus `
文字通り現在のフォーカスを取得する方
エルビス演算子の?:で現在のフォーカスが取得できなければfalseを返す
ちなみに?:の意味は、左側に値があればそれを返して、nullなら右側を返す。

##2.Viewタップで非表示にする方法

イメージ
・キーボードを非表示にしたいViewをタップしたときに随時非表示にする
・hideKeyboard関数を作っておくことで、好きなViewに好きなタイミングで非表示にする
・今回は戻るボタンを押すとキーボードが非表示になる

![keybord2.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2499099/73f04a41-a9e1-eec2-9b94-2db12b9f3a61.gif)



```Kotlin:NewActivity

class NewActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_new)

//戻るボタンを取得
 val backBtn = findViewById<Button>(R.id.back_Btn)
//hideKeyboard()でボタンを押すとキーボードが非表示になる
        backBtn.setOnClickListener {
            hideKeyboard(context = this,backBtn)
        }
    }
//引数のViewには(今回はボタンの)Viewが入ってくる
 fun hideKeyboard(context:Context,view: View){
     val inputMethodManager = getSystemService(Activity.INPUT_METHOD_SERVICE) as InputMethodManager
        inputMethodManager.hideSoftInputFromWindow(view.windowToken,InputMethodManager.HIDE_NOT_ALWAYS)
    }
}

```

1と違うのは、キーボード非表示にする関数を作ることでhideKeyboard()を使いまわせるようにしたこと。
関数としてまとめると楽ってだけで、結局やっていることは変わらないと思う。


##3.逆にキーボード表示させる方法


EditTextはタップしたら即キーボードが表示されるから、タップした後の表示で良ければ出番ないと思うけども。
これでできたはず！！

```

 fun showKeyboard(context: Context){
        val inputMethodManager = context.getSystemService(Activity.INPUT_METHOD_SERVICE) as InputMethodManager
        inputMethodManager.toggleSoftInput(InputMethodManager.SHOW_FORCED,0)
    }

```

一応使ってみる....


イメージ
・独自のDialogを作ったとき
・タップさえさせず、起動後すぐにキーボード表示したいとき
(大体起動後すぐにキーボード出たら邪魔くさいと思うけど)
・ダイアログとかでEditText1つしかない！これだけ必ず！的な(?)


```Kotlin:dialog
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
 val dialog = super.onCreateDialog(savedInstanceState)
 val context = requireContext()
dialog.setOnShowListener{
          showKeyboard(requireContext())
        }
fun showKeyboard(context: Context){
        val inputMethodManager = context.getSystemService(Activity.INPUT_METHOD_SERVICE) as InputMethodManager
        inputMethodManager.toggleSoftInput(InputMethodManager.SHOW_FORCED,0)
    }


```







ダイアログのところだけはわざわざここだけ試すってことしてないから、
本当にこれだけでいけるのかは怪しい....

おーーーしまいっ☆



## 参考記事
①https://hirauchi-genta.com/kotlin-edittext/
②https://qiita.com/tkmd35/items/7d2bd568bd646d0ce6a9
③https://developer.android.com/training/keyboard-input/visibility?hl=ja
④https://akira-watson.com/android/touchevent.html