使用 DataBinding 的 RecyclerView

這是一個通用的 ViewHolder 類,可以與任何 DataBinding 佈局一起使用。這裡使用膨脹的 View 物件和 DataBindingUtil 實用程式類建立特定 ViewDataBinding 類的例項。

import android.databinding.DataBindingUtil;
import android.support.v7.widget.RecyclerView;
import android.view.View;

public class BindingViewHolder<T> extends RecyclerView.ViewHolder{

    private final T binding;

    public BindingViewHolder(View itemView) {
        super(itemView);
        binding = (T)DataBindingUtil.bind(itemView);
    }

    public T getBinding() {
        return binding;
    }
}

建立此類後,你可以在佈局檔案中使用 <layout> 為該佈局啟用資料繫結,如下所示:

file name: my_item.xml

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

    <data>
        <variable
            name="item"
            type="ItemModel" />
    </data>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:text="@{item.itemLabel}" />
    </LinearLayout>
</layout>

這是你的示例 dataModel:

public class ItemModel {
    public String itemLabel;
}

預設情況下,Android 資料繫結庫根據佈局檔名生成 ViewDataBinding 類,將其轉換為 Pascal 大小寫,併為其新增字尾 Binding。對於這個例子,佈局檔案 my_item.xml 將是 MyItemBinding。Binding 類還有一個 setter 方法來設定在佈局檔案中定義為資料的物件(本例中為 ItemModel)。

現在我們已經完成了所有的工作,我們可以像這樣實現我們的介面卡

class MyAdapter extends RecyclerView.Adapter<BindingViewHolder<MyItemBinding>>{
    ArrayList<ItemModel> items = new ArrayList<>();
        
    public MyAdapter(ArrayList<ItemModel> items) {
        this.items = items;
    }

    @Override public BindingViewHolder<MyItemBinding> onCreateViewHolder(ViewGroup parent, int viewType) {
        return new BindingViewHolder<>(LayoutInflater.from(parent.getContext()).inflate(R.layout.my_item, parent, false));
    }

    @Override public void onBindViewHolder(BindingViewHolder<ItemModel> holder, int position) {
        holder.getBinding().setItemModel(items.get(position));
        holder.getBinding().executePendingBindings();
    }

    @Override public int getItemCount() {
        return items.size();
    }
}