【Kotlin】Groupieを使って簡単なサンプルを作ってみた

# はじめに
RecyclerViewを使おうとすると、ViewHolderの定義だったり、Adapterの定義だったり、ちょっと面倒ですよね。
そんなときに便利なのが[**Groupie**](https://github.com/lisawray/groupie)というライブラリです。
RecyclerViewを扱いやすくするライブラリで、[DroidKaigiのアプリ](https://github.com/DroidKaigi/conference-app-2019)や、[クックパッドさん](https://techlife.cookpad.com/entry/2019/04/11/130000)などでも導入されているそうです（2019年4月現在）。

サクっと動く簡単なサンプルを作ってみたので、興味がある方は試してみてください:grinning:
<img width="300" alt="スクリーンショット 2019-05-01 18.48.14.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/112818/2c9a58a5-194c-e101-7706-40cabc9f7c4e.png">

# 環境
* macOS: 10.14.1
* Android Studio: 3.4
* kotlin: 1.3.21
* Support Library: AndroidX

# 手順
## Groupieの導入
今回はDataBindingと一緒に使っていくので、下記のようにbuild.gradleに追記します。

```groovy:build.gradle
android {
...
    dataBinding.enabled = true
}

dependencies {
...
    implementation 'com.xwray:groupie:2.3.0'
    implementation 'com.xwray:groupie-databinding:2.3.0'
...
}
```

Syncが問題なくできたことを確認したら次へ進みます。

## RecyclerViewのセット
activity_main.xmlにRecyclerViewをセットします。
`app:layoutManager`の定義を忘れがちなので注意です。

```xml:activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<layout
    xmlns:android="http://schemas.android.com/apk/res/android" 
    xmlns:app="http://schemas.android.com/apk/res-auto">

        <androidx.constraintlayout.widget.ConstraintLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent">

                <androidx.recyclerview.widget.RecyclerView
                    android:id="@+id/recycler_view"
                    android:layout_width="match_parent"
                    android:layout_height="match_parent"
                    app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"/>
        </androidx.constraintlayout.widget.ConstraintLayout>
</layout>
```

Previewで見るとこんな感じになっているかと思います。
<img width="300" alt="スクリーンショット 2019-04-30 10.48.20.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/112818/03288843-0b17-a7cd-ae1e-31356c529921.png">


## Itemの作成
RecyclerViewに表示するItemを作っていきます。
まずはxmlファイルを新規作成し、レイアウトを組みます。

```xml:item_list.xml
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:app="http://schemas.android.com/apk/res-auto"
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools">

    <data>
        <variable name="text" type="String"/>
    </data>

    <androidx.constraintlayout.widget.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="100dp">

        <TextView
            android:id="@+id/textView"
            android:text="@{text}"
            android:textSize="20sp"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginStart="8dp"
            android:layout_marginEnd="8dp"
            android:layout_marginBottom="8dp"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintTop_toTopOf="parent"
            app:layout_constraintBottom_toBottomOf="parent"
            tools:text="くだもの"/>
    </androidx.constraintlayout.widget.ConstraintLayout>
</layout>
```

Previewで見るとこんな感じです。TextViewが一つだけある、とても簡単なレイアウトです。
<img width="300" alt="スクリーンショット 2019-04-30 10.50.13.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/112818/5a2b1eff-8b2e-1969-ee22-36b8264ae58a.png">

続いてItemのクラスを作ります。

```Kotlin:ListItem.kt
class ListItem(private val text: String) : BindableItem<ItemListBinding>() {
    override fun getLayout(): Int = R.layout.item_list

    override fun bind(viewBinding: ItemListBinding, position: Int) {
        viewBinding.text = text
    }
}
```

一度ビルドすると、Binding用のクラス`ItemListBinding`が自動生成されるのでそれをimportしましょう。
コードの内容としては、クラス生成のタイミングで受け取った`text`を、xmlの`<data>...</data>`内で定義した`text`へバインドしています。

## ItemをRecyclerViewに追加する
最後はMainActivityに記述していきます。
`ViewHolder`では複数の選択肢が出てくると思いますが、その中から`com.xwray.groupie.ViewHolder`をインポートしてください。

```Kotlin:MainActivity.kt
class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        
        val groupAdapter = GroupAdapter<ViewHolder>()
        findViewById<RecyclerView>(R.id.recycler_view).adapter = groupAdapter

        val items = listOf("りんご🍎", "みかん🍊", "ぶどう🍇", "すいか🍉", "もも🍑", "ばなな🍌")
        items.forEach { item ->
            groupAdapter.add(ListItem(item))
        }
    }
}
```

これで`ItemList`が一つずつ`groupAdapter`に渡され、RecyclerViewに表示されるようになりました。
お疲れ様でした！

# さいごに
全てのコードはGithubに載せていますので、必要に応じてお使いください:grinning:
https://github.com/orimomo/groupie-sample-app

## 参考
* [GitHub - lisawray/groupie: Groupie helps you display and manage complex RecyclerView layouts.](https://github.com/lisawray/groupie)
* [GitHub - DroidKaigi/conference-app-2019: The Official Conference App for DroidKaigi 2019 Tokyo](https://github.com/DroidKaigi/conference-app-2019)
* * [RecyclerViewによるレイアウトを楽にするGroupieを1年使ってみて - Qiita](https://qiita.com/takahirom/items/4125d7c871fad534d3c2)