【ユーザーインタラクション編】 2022年だしそろそろAndroidアプリ開発を始めてみる (4/4)

この記事はPart4です。Part3(API通信編)は[こちら](https://qiita.com/tkhskt/items/e491f389ff9ba0563fda)をご覧ください。
Part4では、ユーザーが入力した値を使って記事を検索する機能を実装します。

## レイアウトの編集

`MainActivity`のレイアウト(`activity_main.xml`)に入力フォームと検索ボタンを追加します。

```xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".ui.MainActivity">

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/articleList"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:clipToPadding="false"
        android:paddingBottom="56dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <EditText
        android:id="@+id/form"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginStart="16dp"
        android:layout_marginEnd="8dp"
        android:inputType="text"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toStartOf="@id/button"
        app:layout_constraintStart_toStartOf="parent" />

    <Button
        android:id="@+id/button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginEnd="16dp"
        android:text="@string/search"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>
```

まず、`EditText(入力フォーム)`と`Button`を画面の下部に配置します。
その後、`RecyclerView`と入力フォームやボタンが重なるのを防ぐため、`RecyclerView`の下部に`padding`を設定します。
レイアウトファイルで画面に表示するテキストを直接設定することは非推奨になっています。
たとえば、今回実装する検索ボタンには「検索」という文字を表示しますが、`activity_main.xml`では直接「検索」の文字を設定していません。
このようなテキストは`strings.xml`に定義し、レイアウトのXMLから参照して設定することが推奨されています。

![スクリーンショット 2022-03-31 1.50.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/155135/5f38d51d-566e-3658-c0cf-839ada972f93.png)

```xml
<resources>
    <string name="app_name">WikiClient</string>

    <string name="search">検索</string>
</resources>
```

## クリックイベント処理の実装

検索ボタンがクリックされた際の処理を`MainActivity`に書きましょう。

```kotlin
class MainActivity : AppCompatActivity() {
    ...

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = ActivityMainBinding.inflate(layoutInflater)
        val view = binding.root
        setContentView(view)

        initArticleList()
        observeArticles()
        initButton() // 追加

        viewModel.fetchArticles("Android", 20)
    }

    private fun initButton() {
        binding.button.setOnClickListener {
             // 検索ボタンクリック時の処理
            val formText = binding.form.text.toString() // フォームに入力されている値を取得
            if (formText.isNotEmpty()) {
                viewModel.fetchArticles(formText, 20) // フォームの値を元にWeb APIから値を取得
            }
        }
    }
    ...
}
```

`MainActivity`に`initButton`メソッドを追加し、`onCreate`から呼び出します。
`initButton`では、ボタンに対し`OnClickListener(クリックされた時に呼び出されるメソッド)`を設定します。
今回は、検索ボタンクリック時に、フォームに入力された値を取得しその値を使って検索する処理を記述します。

## ViewModelの修正

ここから先は別に実装しなくても動くのですが、一応やっておきます。
Web APIへのリクエストが完了する前に、新たなリクエストを開始する時のために、通信処理のキャンセル処理を追加します。

```kotlin
class MainViewModel(
    private val repository: WikiRepository = WikiRepositoryImpl()
) : ViewModel() {

    ...

    private var job: Job? = null

    fun fetchArticles(keyword: String, limit: Int) {
        job?.cancel()
        job = viewModelScope.launch(Dispatchers.IO) {
           ...
        }
    }

    ...
}
```

## 動かしてみる

![Screenshot_20220331_195725.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/155135/d2f00d1b-c0fa-53fb-cd49-c20a42fde3dc.png)

任意のキーワードでの検索結果が表示されればOKです👌

## 終わり

お疲れ様でした！
Android開発、どうでしたか？
難しかったところなどがあればぜひ教えてください！