【Android/Kotlin】SearchView（検索バー）とちょっと仲良くなって入力文字列を取得できるようになった

# 概要
Androidアプリで、リスト内検索機能を実装したかったが、検索バーとは面識がなかった。
そこで、検索バーと少し遊んで基本的な使い方を知った。設置方法や、入力した文字列を取得する際に使えそうなメソッドを備忘録的にまとめる。
![not_iconified_searchbar.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/124752/dc466b1c-6402-9735-ab12-e9985872fed8.png)


# 画面に検索バーを設置する
`xml`に[`SearchView`](https://developer.android.com/reference/kotlin/android/widget/SearchView.html)を記述すれば検索UIを設置できる。

```xml
<SearchView
    android:id="@+id/search"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:iconifiedByDefault="false"
    android:queryHint="検索" />
```

`iconifiedByDefault`を`false`にして、常に検索の入力欄が表示されている状態にする。デフォルトは`true`で、`true`の場合平時はアイコンのみ表示され、アイコンをクリックすると検索バーが出てくる。例えばアプリバーに設置する場合などは`true`にすると良いだろう。

`iconifiedByDefault: false`
![not_iconified_searchbar.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/124752/dc466b1c-6402-9735-ab12-e9985872fed8.png)

`iconifiedByDefault: true`
![iconified_searchbar.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/124752/7df2b9e4-c896-39a6-3aef-95a1d7346484.png)


また、`queryHint`にヒント文字列を設定しておくと、未入力状態の検索バーにヒントが表示される。

# 入力された文字列を取得する

## [`setOnQueryTextListener()`](https://developer.android.com/reference/kotlin/android/widget/SearchView.html#setOnQueryTextListener(android.widget.SearchView.OnQueryTextListener))
「入力欄の文字列が変わったとき」と「検索ボタンが押されたとき」のイベントリスナーをセットする。

### [`SearchView.OnQueryTextListener`](https://developer.android.com/reference/kotlin/android/widget/SearchView.OnQueryTextListener.html)
- `onQueryTextChange(newText: String): Boolean`  
ユーザーによって文字列が変更されたときに呼ばれる（一文字や予測変換一つ位の単位）。  
`newText`はそのとき入力されている文字列。
- `onQueryTextSubmit(query: String): Boolean`  
ユーザーがクエリを送信（検索ボタンをクリック）したときに呼ばれる。  
`query`は送信された文字列。

例えば、検索結果をリアルタイムに表示したい場合は`onQueryTextChange()`に、検索ボタンを押したときに検索結果を表示する（こちらはほぼ100%やると思うが）場合は`onQueryTextSubmit()`に処理を記述すれば良い。

```kotlin
searchBar.setOnQueryTextListener(object : SearchView.OnQueryTextListener {
    override fun onQueryTextChange(newText: String): Boolean {
        // text changed
        return false
    }
    override fun onQueryTextSubmit(query: String): Boolean {
        // submit button pressed
        return false
    }
})
```

### 検索ボタン
文字列を確定させたときはReturnボタンが検索ボタンになる。
![submit_button.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/124752/6b1c0d66-999c-2dc8-147d-6c086f0a38c4.png)

また、[`setSubmitButtonEnabled()`](https://developer.android.com/reference/kotlin/android/widget/SearchView.html#setSubmitButtonEnabled(kotlin.Boolean))で検索バーの入力欄の端に検索ボタンを表示するかどうか（真偽値）を設定でき、`true`で検索ボタンが表示される。
![submit_button_enabled.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/124752/e47defa5-868e-b30e-e8e0-1126b39b7361.png)


## [`setOnQueryTextFocusChangeListener()`](https://developer.android.com/reference/kotlin/android/widget/SearchView.html#setOnQueryTextFocusChangeListener(android.view.View.OnFocusChangeListener))
「検索バーのフォーカスが変わったとき」のイベントリスナーをセットする。

### [`View.OnFocusChangeListener`](https://developer.android.com/reference/kotlin/android/view/View.OnFocusChangeListener.html)
- `onFocusChange(v: View, hasFocus: Boolean)`  
ビューのフォーカス状態が変わったときに呼ばれる。

例えば、検索バーにフォーカスが当たっている時のみ検索キャンセルボタンを表示する、検索バー以外にフォーカスが移ったときに入力欄をリセットする、などの使い方ができる。

## [`getQuery()`](https://developer.android.com/reference/kotlin/android/widget/SearchView.html#getQuery())
現在入力されている文字列を取得する。
例えば、独自に設置したボタンを押したときに、入力されている文字列を取得するという使い方ができる。

# まとめ
- xmlに`SearchView`を記述すれば、検索バーを設置できる。このとき、バー表示にするために`iconifiedByDefault`を`false`にする。
- `setOnQueryTextListener()`で`OnQueryTextListener`をセットして、「入力欄の文字列が変わったとき」や「検索ボタンが押されたとき」の処理を設定できる。
- `setOnQueryTextFocusChangeListener()`で`OnFocusChangeListener`をセットして、「検索バーのフォーカスが変わったとき」の処理を設定できる。