RecyclerViewにDataBindingを導入してみた

## はじめに
前回作成したRecyclerViewにDataBindingを導入してみた。
前回記事https://qiita.com/kilalabu/items/da1aae6d73177fec9e98

## デモアプリ
![recyclerview.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/670405/8e1d05fa-ba7c-260e-bf03-70e20b242f00.gif)
## コード実装
### Layout
```xml:recyclerview_cell_item.xml
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">
    <data>
        <variable
            name="cellData"
            type="com.example.recyclerviewapp.CellData" />
    </data>

    <LinearLayout
        android:orientation="horizontal"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <TextView
            android:id="@+id/title"
            android:layout_width="100dp"
            android:layout_height="40dp"
            android:text="@{cellData.title}"/>

        <TextView
            android:id="@+id/sub_title"
            android:layout_width="wrap_content"
            android:layout_height="40dp"
            android:text="@{cellData.subTitle}"/>

    </LinearLayout>
</layout>
```
### CellData
今回は静的画面なので特に修正はしない。
動的にする場合はBaseObservableを継承してオブジェクトを監視する仕組みをつくる必要あり。
詳しくはhttps://qiita.com/kilalabu/items/3cded5e7c560de2ed05c

```java:CellData.java
public class CellData {
    private String title;
    private String subTitle;

    public CellData(String title, String subTitle) {
        this.title = title;
        this.subTitle = subTitle;
    }

    public String getTitle() {
        return title;
    }

    public String getSubTitle() {
        return subTitle;
    }
}
```
### ViewHolder(DataBinding適用前との比較）

```java:SampleViewHolder.java
public class SampleViewHolder extends RecyclerView.ViewHolder {
//    private TextView title;
//    private TextView subTitle;
    private ViewDataBinding viewDataBinding;

    //　② View(TextViewなどの各パーツ)を参照する (1セルごとに毎回呼び出される）
    SampleViewHolder(View view) {
        super(view);
//        title = view.findViewById(R.id.title);
//        subTitle = view.findViewById(R.id.sub_title);
        viewDataBinding = DataBindingUtil.bind(view); // 引数ActivityのときはsetContentView()だが引数Viewのときはbind()
    }

//    public TextView getTitle() {
//        return title;
//    }

//    public TextView getSubTitle() {
//        return subTitle;
//    }

    public ViewDataBinding getViewDataBinding() {
        return viewDataBinding;
    }
}
```
### Adapter（DataBinding適用前との比較）

```java:SampleAdapter.java
public class SampleAdapter extends RecyclerView.Adapter<SampleViewHolder> {

    private List<CellData> cellDataList;

    // 全セルデータを取得
    SampleAdapter(List<CellData> cellDataList) {
        this.cellDataList = cellDataList;
    }

    // ① セルのレイアウトを読み込んでViewHolderと紐付ける (1セルごとに毎回呼び出される）
    @Override
    public SampleViewHolder onCreateViewHolder(@Nullable ViewGroup parent, int viewType) {
        LayoutInflater layoutInflater = LayoutInflater.from(parent.getContext());
        // View view = layoutInflater.inflate(R.layout.recyclerview_cell_item, parent, false);
        // return new SampleViewHolder(view);
        RecyclerviewCellItemBinding binding = RecyclerviewCellItemBinding.inflate(layoutInflater, parent, false);
        return new SampleViewHolder(binding.getRoot());  // getRoot()で読み込んだレイアウトのViewを取得
    }
    }

    // ③ 取得したセルデータをViewHolderが参照してきたView(各パーツ)にセットする (1セルごとに毎回呼び出される）
    @Override
    public void onBindViewHolder(@Nullable SampleViewHolder viewHolder, int position) {
        CellData cellData = cellDataList.get(position);  // 全セルデータからx番目のデータを取得
        // viewHolder.getTitle().setText(cellData.getTitle()); // textView(title)にtitleデータをセット
        // viewHolder.getSubTitle().setText(cellData.getSubTitle()); // textView(sub_title)にsubTitleデータをセット
        viewHolder.getViewDataBinding().setVariable(BR.cellData, cellData);
    }

    // セルデータの総数
    @Override
    public int getItemCount() {
        return cellDataList.size();
    }
}
```
※レイアウトのインフレートはdeveloperサイトの推奨通りにしてます。
>Fragment、ListView、RecyclerView アダプター内でデータ バインディング アイテムを使用している場合は、次のコード例に示すように、バインディング クラスまたは DataBindingUtil クラスの inflate() メソッドを使用することをおすすめします。
ListItemBinding binding = ListItemBinding.inflate(layoutInflater, viewGroup, false);


### ViewHolder(コメント削除版）
```java:SampleViewHolder.java
public class SampleViewHolder extends RecyclerView.ViewHolder {
    private ViewDataBinding viewDataBinding;

    //　② View(TextViewなどの各パーツ)を参照する (1セルごとに毎回呼び出される）
    SampleViewHolder(View view) {
        super(view);
        viewDataBinding = DataBindingUtil.bind(view); 
    }

    public ViewDataBinding getViewDataBinding() {
        return viewDataBinding;
    }
}
```
### Adapter(コメント削除版）
```java:SampleAdapter.java
public class SampleAdapter extends RecyclerView.Adapter<SampleViewHolder> {

    private List<CellData> cellDataList;

    // 全セルデータを取得
    SampleAdapter(List<CellData> cellDataList) {
        this.cellDataList = cellDataList;
    }

    // ① セルのレイアウトを読み込んでViewHolderと紐付ける (1セルごとに毎回呼び出される）
    @Override
    public SampleViewHolder onCreateViewHolder(@Nullable ViewGroup parent, int viewType) {
        LayoutInflater layoutInflater = LayoutInflater.from(parent.getContext());
        RecyclerviewCellItemBinding binding = RecyclerviewCellItemBinding.inflate(layoutInflater, parent, false);
        return new SampleViewHolder(binding.getRoot());  // getRoot()で読み込んだレイアウトのViewを取得
    }
    }

    // ③ 取得したセルデータをViewHolderが参照してきたView(各パーツ)にセットする (1セルごとに毎回呼び出される）
    @Override
    public void onBindViewHolder(@Nullable SampleViewHolder viewHolder, int position) {
        CellData cellData = cellDataList.get(position);  // 全セルデータからx番目のデータを取得
        viewHolder.getViewDataBinding().setVariable(BR.cellData, cellData);
    }

    // セルデータの総数
    @Override
    public int getItemCount() {
        return cellDataList.size();
    }
}
```
## 最後に
DataBindingを使うことによって、これまでアイテムを１個ずつ取得していたものを一度にまとめて取得することができた。少しずつDataBindingの良さを感じられるようになってきた気がする。

##参考URL
https://developer.android.com/topic/libraries/data-binding/generated-binding?hl=ja#create
https://qiita.com/nagasakulllo/items/88c7857c4b542825b06b

ありがとうございました！