Android RecyclerView avec DataBinding


Exemple

Voici une classe ViewHolder générique que vous pouvez utiliser avec n'importe quelle disposition de DataBinding. Ici, une instance de classe ViewDataBinding particulière est créée à l'aide de l'objet View gonflé et de la classe d'utilitaire DataBindingUtil .

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;
    }
}

Après avoir créé cette classe, vous pouvez utiliser <layout> dans votre fichier de mise en page pour activer la liaison de données pour cette mise en page, comme ceci:

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>

et voici votre exemple de dataModel:

public class ItemModel {
    public String itemLabel;
}

Par défaut, la bibliothèque Android Data Binding génère une classe ViewDataBinding basée sur le nom du fichier de mise en page, en la convertissant en cas Pascal et en y ajoutant le suffixe "Binding". Pour cet exemple, ce serait MyItemBinding pour le fichier de présentation my_item.xml . Cette classe Binding aurait également une méthode setter pour définir l'objet défini en tant que données dans le fichier de disposition ( ItemModel pour cet exemple).

Maintenant que nous avons toutes les pièces, nous pouvons implémenter notre adaptateur comme ceci:

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();
    }
}