RecyclerViewでDataBinding

# 目的
RecyclerViewでDataBindingしたい

# 環境
Android Studio 3.2.1
Kotlin 1.2.71

# 実装
## リスト用クラスの作成
今回は簡単にBookクラスとしました

```Kotlin:Book.kt
data class Book(val id: Int, val title: String, val entryDate: Date)
```

## layoutファイル修正(RecyclerView本体)
まずactivity_main.xmlの修正
テキストを載せますが、デザインビューでRecyclerViewを入れただけです。
後々の為にRecyclerViewのidだけは入れておきます。

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

    <android.support.constraint.ConstraintLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            tools:context=".MainActivity">

        <android.support.v7.widget.RecyclerView
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:id="@+id/recyclerView"/>
    </android.support.constraint.ConstraintLayout>

</layout>
```

## layoutファイルの追加(リスト表示の各行分)
RecyclerViewで表示する各行のレイアウトファイルを作ります。
注意点としては行単位なのでレイアウトのルート(例だとConstraintLayout)のlayout_height属性はwrap_contentとなることです。

私自身ハマったのですが、DataBindingしているlayoutファイルに数値を渡すと実行時エラーとなります。
数字として渡してあげるか、layoutファイルで数字に変換することが必要になります。
(例だとbook.idとbook.entryDateの部分)

```XML:book_row.xml
<?xml version="1.0" encoding="utf-8"?>
<layout
        xmlns:app="http://schemas.android.com/apk/res-auto"
        xmlns:tools="http://schemas.android.com/tools"
        xmlns:android="http://schemas.android.com/apk/res/android">
    <data>
        <variable
                name="book"
                type="com.example.ytnb.databinding1.Book"/>
    </data>
    <android.support.constraint.ConstraintLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content">

        <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:id="@+id/tv_id"
                android:text="@{Integer.toString(book.id)}"
                tools:text="id"
                android:layout_marginTop="8dp"
                app:layout_constraintTop_toTopOf="parent"
                app:layout_constraintStart_toStartOf="parent"
                android:layout_marginStart="8dp"
                app:layout_constraintHorizontal_bias="0.5"
                app:layout_constraintEnd_toStartOf="@+id/tv_title"
                app:layout_constraintBottom_toBottomOf="parent"
                android:layout_marginBottom="8dp"/>

        <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:id="@+id/tv_title"
                android:text="@{book.title}"
                tools:text="title"
                android:layout_marginTop="8dp"
                app:layout_constraintTop_toTopOf="parent"
                app:layout_constraintStart_toEndOf="@+id/tv_id"
                app:layout_constraintHorizontal_bias="0.5"
                app:layout_constraintEnd_toStartOf="@+id/tv_date"
                android:layout_marginBottom="8dp"
                app:layout_constraintBottom_toBottomOf="parent"/>

        <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:id="@+id/tv_date"
                android:text="@{book.entryDate.toString()}"
                tools:text="entry_date"
                android:layout_marginTop="8dp"
                app:layout_constraintTop_toTopOf="parent"
                app:layout_constraintEnd_toEndOf="parent"
                android:layout_marginEnd="8dp"
                app:layout_constraintStart_toEndOf="@+id/tv_title"
                app:layout_constraintHorizontal_bias="0.5"
                android:layout_marginBottom="8dp"
                app:layout_constraintBottom_toBottomOf="parent"/>
    </android.support.constraint.ConstraintLayout>
</layout>
```

## RecyclerView.Adapterの実装
次にAdapterを作成します

```Kotlin:BookAdapter.kt
class BookAdapter(private val context: Context) : RecyclerView.Adapter<BookAdapter.BookHolder>() {
    var bookItems = listOf<Book>()
        set(value) {
            field = value
            notifyItemRangeInserted(0, field.size)
        }


    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): BookHolder {
        val binding: BookRowBinding =
            DataBindingUtil.inflate(LayoutInflater.from(context), R.layout.book_row, parent, false)
        return BookHolder(binding)
    }

    override fun getItemCount(): Int {
        return bookItems.size
    }

    override fun onBindViewHolder(holder: BookHolder, position: Int) {
        holder.binding.book = bookItems[position]
        holder.binding.executePendingBindings()
    }

    class BookHolder(val binding: BookRowBinding) : RecyclerView.ViewHolder(binding.root)
}
```

## MainActivityの修正
最後にMainActivityからRecyclerViewをバインドします。

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

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        val binding: ActivityMainBinding = DataBindingUtil.setContentView(this,R.layout.activity_main)

        val adapter = BookAdapter(this).also { adapter ->
            adapter.bookItems = listOf(
                Book(0, "Android", Date()),
                Book(1, "Kotlin", Date()),
                Book(2, "Data", Date())
            )
        }

        binding.recyclerView.layoutManager = LinearLayoutManager(this)
        binding.recyclerView.adapter = adapter
    }
}
```

# 結果
以下のようになります。
行レイアウトが適当なのでデコボコしてしまっていますが、きちんと作ってあげれば綺麗に表示できるかと思います。
<img src=https://qiita-image-store.s3.amazonaws.com/0/301495/0b997d25-07f3-570f-e8b0-21de779d1a5c.png width=40%>