#4 Kotlin で TODO アプリを開発・リリースするまでの記録

# 前回のあらすじ
### 前回までの記事
[#1 Kotlin で TODO アプリを開発・リリースするまでの記録](https://qiita.com/m_n_r/items/03ac9f641f735ad40d43)
[#2 Kotlin で TODO アプリを開発・リリースするまでの記録](https://qiita.com/m_n_r/items/90f9f96bf1a8b4f91613)
[#3 Kotlin で TODO アプリを開発・リリースするまでの記録](https://qiita.com/m_n_r/items/d3f15df9b0f4974b3dc5)

### 前回のあらすじ
- ライブラリの最新は AndroidX
- Jetpack には便利な機能がたくさんあり、中でも LiveData が使えそう

### 今回の目標
- RecyclerView でリスト表示

# ListAdapter ってなに？
初心にかえって RecyclerView について調べていたら、偶然目についた **ListAdapter**。
何の前触れもないですが、ここから触れさせてください。

- [RecyclerViewでListAdapterを使う](https://qiita.com/chohas/items/acbf3787cd80b5277af7)
- [RecyclerViewにListAdapterを使って差分更新を実現する](https://kazkn.hatenablog.com/entry/2018/10/09/024734)
- [ListAdapterを使用してRecyclerViewの更新を簡単に行う](https://qiita.com/watabee_dev/items/1bba52710125d1c3205f)

記事を読んだ際に思いだしたのが、#2 で触れたあの記事です。

**[Kotlin RecyclerView 一覧画面の並び替えでデータと画面の同期をとるならnotify系メソッドの呼び出しが必要。](https://qiita.com/tanaka5750/items/64e3a490954b8c3e2392)**

**もしかして notify 系を作らなくて済む機能なのでは？**

俄然興味がわいたのですが、上記で挙げた記事以外に詳しい記事を見つけることができませんでした（更新日が何年も前の記事は除外しています）。
それでもこれを使う気はもりもりです。

# 実装の参考記事
ところでここにきて、最初からこれを見つけたかった～！って七転八倒するレベルで、アプリの作成手順を丁寧に書いておられる記事を見つけたので紹介します。

**[Kotlin, LiveData, coroutine なんかを使って初めてのAndroidアプリを作る(1)準備編](https://qiita.com/kasa_le/items/105ab4d287d8b2316bce)**

びっくりしました、もうこの記事見ながらまるまるアプリ作ってリリースしてやろうかとさえ思いました。

というレベルで親切に書いてあります。
著者は親切じゃないので、著者が見つけたタイミングの位置で記事にも引用しちゃう。
**この記事をちゃんと読んでる人はたどり着けたね！よかったね！えらい！**

回りくどい記録を見たいのではなく、Kotlin でアプリを作ってみたいだけ、という方はこの記事は回れ右して上記リンク先までどうぞ。

本記事では、基本仕様で挙げた実装と異なることから、まねして書くことを断念して、引き続き調べながら一から実装していきます。無念かよ。

# RecyclerView でリスト表示
「別の記事に案内しておいてこのタイミングで実装なの？」
気にせずやっていくよ

まずは #2 を見返して、RecyclerView を調べた際の参考記事をまねするところから。
まねする記事はこちらにしました。

**[KotlinでRecyclerViewを使ったリスト表示を行う](https://qiita.com/Todate/items/297bc3e4d0f3d2477ed3)**

## AndroidX でライブラリインポート
```build.gradle
dependencies {
    // 以下を追記してsync。（バージョンは適宜合わせてください）
    compile 'com.android.support:recyclerview-v7:26.1.0'
    compile 'com.android.support:cardview-v7:26.1.0'
}
```
さて、これは Support Library を使用しているようです。
今回は学んだ AndroidX を使用してみることにしましょう。
**あ、AndroidX の使い方わからへん**

### 2 つの build.gradle
プロジェクト内には 2 つの build.gradle があります。
![build_gradle.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/477634/7b13cbfd-f57a-649d-0651-179078096719.png)
このどちらかに AndroidX を使用する設定を行わなければなりません。
中身を見て比べればわかりますが、使用するのは **build.gradle(Module:app)** のようです。

初期の dependencies は次のようになっています。

```app/build.gradle
dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation"org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
    implementation 'androidx.appcompat:appcompat:1.0.2'
    implementation 'androidx.core:core-ktx:1.0.2'
    implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'androidx.test:runner:1.2.0'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
}
```

> [RecyclerViewでデータを複数件表示する方法](https://qiita.com/fu_neko/items/722e0ab5f0f1255f87bf)
> `implementation 'androidx.recyclerview:recyclerview:1.0.0'`

書き方がわかりましたが、バージョン指定が必要です。
どの記事でも最新バージョンを使用するよう推奨していました。

> [Recyclerview](https://developer.android.com/jetpack/androidx/releases/recyclerview)
> `androidx.recyclerview:recyclerview:1.1.0-beta02 is released.`

公式に最新のバージョンが書いてあるので、これが使えそうです。
ただ、Android Studio から直接選択できる方法はないでしょうか？

**#2 に自分の環境にあったバージョンライブラリを選択できる方法がありましたね。
[[Android] RecyclerView の基本的な設定](https://akira-watson.com/android/recyclerview.html)**
![ライブラリ検索.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/477634/feb5a99e-8fd4-f99e-78f0-9c45f07539e9.png)

検索結果一番上の recyclerview は **androidx.recyclerview** になっているのでこれです。
Android Studio から直接ライブラリを選択することができました！
Versions はどれを選ぶべきか判断に迷ったので、一番上にしておきます。
CardView も同様の方法で追加しました。

```app/build.gradle
dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation"org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
    implementation 'androidx.appcompat:appcompat:1.0.2'
    implementation 'androidx.core:core-ktx:1.0.2'
    implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'androidx.test:runner:1.2.0'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
    implementation 'androidx.recyclerview:recyclerview:1.1.0-beta02'
    implementation 'androidx.cardview:cardview:1.0.0'
}
```
無事 AndroidX のライブラリを追加できました。

### 余談：Android Studio プロジェクト構成
> [[Android] Android Studioプロジェクトの構成を確認する](http://www.programing-style.com/android/android-lesson/android-studio-project/)
> Androidビューは実際のフォルダ構成とは異なります。

build.gradle があたかも同じディレクトリにいるように見えますが、エクスプローラーでは異なっていました。
同じリソースの種類でまとめて表示してくれるそうです、すごいですね。

### 余談：Project Structure
ツールバーにも Project Structure がありました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/477634/8c86f0a0-f89b-230f-ed55-f512d23384c6.png)

## リスト用のレイアウトアイテム（xml）を作成する
### xml ファイルを新規追加する
ファイルを追加しようとしたら、**＋マークがありませんでした・・・**（普段は VScode）。

ファイルの追加方法すらわからないなんて、としょぼくれながら調べます。
[レイアウトエディターで UI を作成する](http://westplain.sakuraweb.com/translate/Android%2520Studio/Write%2520Your%2520App/Build%2520a%2520UI%2520with%2520Layout%2520Editor.cgi)

作り方は複数あり、2 種類試しましたが結果は同じだったので、お手軽な方法を選べばいいです。

```list_item.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:orientation="vertical"
              android:layout_width="match_parent"
              android:layout_height="match_parent">

</LinearLayout>
```

特に指定の必要もなく、activity_main.xml と同じディレクトリに入ったので、場所の変更は行いません。
Root element の既定が LinearLayout だったので初期値が入っているようですが、これから書き換えるので問題ありません。

### list_item.xml ファイルを書き換える
参考記事の list_item.xml を、LinearLayout を上書きするようにそのまま貼り付けました。
特にエラーやワーニングは発生しなかったので、引用はしません。

## ViewHolder を作成する
### kt ファイルを新規追加する
[File] > [New] > [Kotlin File/Class] を選択します。
MainActivity.kt のディレクトリを選択した状態でコードを追加するよう注意してください。
選択中のディレクトリで作成されてしまうようです。
xml と同様に、[File] の代わりに作成したいディレクトリを右クリックしても [New] が表示されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/477634/aead99fb-91d4-f7a9-02e7-c55acd51e7b4.png)
Kind を File → Class に変更して、「OK」をクリックします。

```RecyclerViewHolder.kt
package com.example.first

class RecyclerViewHolder {
}
```

空の Class が作成できました。

### RecyclerViewHolder.kt ファイルを書き換える
参考記事の RecyclerViewHolder.kt を、class RecyclerViewHolder を上書きするようにそのまま貼り付けました。

赤文字はエラーのようです。
カーソルを合わせるとこんな表示が。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/477634/45b1177c-6c51-6be8-82d6-b60dcee5fc57.png)
Alt + Enter を押下します。

```RecyclerViewHolder.kt
import androidx.recyclerview.widget.RecyclerView
```

インポート文が自動で追加されました！すごいー！

ただ、この記事を書くにあたって調べたところ、Alt + Enter を押す前に自動で設定してくれる機能があるそうです。
みんな知ってたの？すごいね。

**[Android Studio でimport文を自動保管する方法](https://www.youfit.co.jp/archives/817)**

この設定を行うことで、ソースを書く（貼り付ける）だけで自動でインポート文を補完できました。

```RecyclerViewHolder.kt
import android.view.View
import android.widget.ImageView
import android.widget.TextView
import androidx.recyclerview.widget.RecyclerView
```

ほかには「～ is never used」のワーニングはありました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/477634/2cda8a23-7358-4cb0-aff3-2297195c8eaf.png)
現在これら Class・interface・property を使用していないことに対するワーニングなので、まだ定義しただけの現段階で気にする必要はありません。

これで ViewHolder を定義することができました。

# まとめ
今回はここまでです。
RecyclerView でリスト表示はまだできていませんが、次回で終わらせたいですね。

### 成果

- AndroidX のライブラリをインポートできた
- Android Studio のファイル追加方法がわかった
- リストアイテムのレイアウトを作成した
- ViewHolder を作成した

### 参考記事に感謝
たくさんの記事を引用させて頂きました。ありがとうございます。
著者が一部のみを引用したことにより、引用元の意図しない情報として受けられることがないよう、できれば引用元の記事を読んでいただけますようお願いいたします。
またいずれの記事の感想も、著者個人の意見に基づくものですのでご注意ください。

# 次の記事

[#5 Kotlin で TODO アプリを開発・リリースするまでの記録](https://qiita.com/m_n_r/items/c65838ed7ac8a2a4442a)