Data binding in adapter of recyclerView - Android

Viewed 9765

I am using dataBinding in my project to populate a RecyclerView. How can I handle clicks on items?

Here is my XML layout:

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

    <data>

        <variable
            name="listItems"
            type="String" />

        <variable
            name="clickListener"
            type="com.xxxx.xxxx.AdapterStartActivity" />
    </data>

    <android.support.v7.widget.CardView
        android:id="@+id/cardview1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_margin="3dp"
        android:onClick="@{()->clickListener.onCardClick(listItems)}" <=====
        card_view:cardCornerRadius="7dp"
        card_view:cardElevation="7dp"
        card_view:cardMaxElevation="7dp"
        card_view:contentPadding="0dp">

        <TextView
            android:id="@+id/txtTitles"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_gravity="center"
            android:gravity="center"
            android:padding="10dp"
            android:text="@{listItems}"
            android:textColor="#000000"
            android:textSize="20dp"
            android:textStyle="bold" />
    </android.support.v7.widget.CardView>
</layout>

I specified the onClick handler in this line:

android:onClick="@{()->clickListener.onCardClick(listItems)}"

And below is my adapter:

public class AdapterStartActivity extends RecyclerView.Adapter<AdapterStartActivity.ViewHolder> {
    private ListItemActivityStartBinding binding;
    private List<String> listTitle;
    private Context context;

    public AdapterStartActivity(Context context, List<String> listTitle) {
        this.listTitle = listTitle;
        this.context = context;
    }

    public static class ViewHolder extends RecyclerView.ViewHolder {
        public TextView txtTitles;

        public ViewHolder(View v) {
            super(v);
            txtTitles = (TextView) v.findViewById(R.id.txtTitles);
        }
    }

    @Override
    public AdapterStartActivity.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(context).inflate(R.layout.list_item_activity_start, parent, false);
        binding = DataBindingUtil.bind(view);
        ViewHolder viewHolder = new ViewHolder(view);
        return viewHolder;
    }

    @Override
    public void onBindViewHolder(ViewHolder Vholder, int position) {
        binding.setListItems(listTitle.get(position));
    }

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

    public void onCardClick(String listItems) {
        Log.i("SADASSDASDAS", listItems);
    }
}

However, the following code doesn't work:

public void onCardClick(String listItems) {
    Log.i("SADASSDASDAS", listItems);
}
5 Answers

Here is the adapter class for data binding:

class MyBasketAdapter(
        items: List<GetBasketData>,
        private val itemClick: (view: View, position: Int, getBasketData: GetBasketData?) -> Unit)
    : RecyclerView.Adapter<MyBasketAdapter.ViewHolder>() {

// refresh items
var items = items
    set(value) {
        field = value
        notifyDataSetChanged()
    }

override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
    return ViewHolder(
        DataBindingUtil.inflate(
            LayoutInflater.from(parent.context),
            R.layout.item_my_basket,
            parent,
            false
        )
    )
}

override fun onBindViewHolder(holder: ViewHolder, position: Int) {
    holder.bind(position)
    holder.itemView.setOnClickListener(holder)
    holder.itemView.ibDelete.setOnClickListener(holder)
}

override fun getItemCount(): Int {
    return items.count()
}

inner class ViewHolder(private val binding: ItemMyBasketBinding) :
    RecyclerView.ViewHolder(binding.root), View.OnClickListener {

    override fun onClick(v: View?) {
        v?.let {
            itemClick.invoke(it, adapterPosition, items[adapterPosition])
        }
    }

    fun bind(
        position: Int
    ) {
        binding.basketData = items[position]
        binding.executePendingBindings()
    }
}

and this is my item_my_basket.xml file

<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools">

<data>

    <import type="android.view.View" />

    <import type="com.gobaskt.ui.utils.DateTimeUtil" />

    <import type="com.gobaskt.ui.utils.extensions.BindingAdapters" />

    <variable
        name="basketData"
        type="com.gobaskt.ui.bottomnavigation.basket.model.GetBasketData" />

</data>

<com.google.android.material.card.MaterialCardView
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical"
    app:cardBackgroundColor="@color/white"
    app:cardCornerRadius="0dp"
    app:cardElevation="0dp">

    <androidx.constraintlayout.widget.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="@drawable/bg_item_dotted_line_blue_2dp">

        <com.google.android.material.radiobutton.MaterialRadioButton
            android:id="@+id/rbSelectItem"
            android:layout_width="@dimen/_10sdp"
            android:layout_height="@dimen/_10sdp"
            android:background="@drawable/my_basket_rb_selector"
            android:button="@color/transparent"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent" />

        <com.facebook.drawee.view.SimpleDraweeView
            android:id="@+id/imgProduct"
            android:layout_width="@dimen/_62sdp"
            android:layout_height="@dimen/_62sdp"
            android:layout_marginStart="@dimen/_4sdp"
            android:layout_marginTop="@dimen/_8sdp"
            android:layout_marginBottom="@dimen/_8sdp"
            android:adjustViewBounds="true"
            app:actualImageScaleType="centerInside"
            app:imageUriForFresco="@{basketData.offers.mobileOfferImage1}"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintStart_toEndOf="@id/rbSelectItem"
            app:layout_constraintTop_toTopOf="parent"
            app:placeholderImage="@drawable/ic_place_holder"
            app:placeholderImageScaleType="centerCrop"
            app:roundAsCircle="true" />

        <com.google.android.material.textview.MaterialTextView
            android:id="@+id/txtProductName"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_marginStart="@dimen/_8sdp"
            android:layout_marginEnd="@dimen/_4sdp"
            android:ellipsize="end"
            android:fontFamily="@font/montserrat_medium"
            android:maxLines="1"
            android:text="@{basketData.offers.lmName}"
            android:textColor="@color/black"
            android:textSize="@dimen/_13ssp"
            app:layout_constraintBottom_toTopOf="@+id/txtValidOn"
            app:layout_constraintEnd_toStartOf="@+id/txtOffValue"
            app:layout_constraintHorizontal_bias="0.5"
            app:layout_constraintStart_toEndOf="@+id/imgProduct"
            app:layout_constraintTop_toTopOf="parent"
            app:layout_constraintVertical_chainStyle="packed"
            tools:text="Jursey Mike’s Subs" />

        <com.google.android.material.textview.MaterialTextView
            android:id="@+id/txtValidOn"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_marginStart="@dimen/_8sdp"
            android:layout_marginTop="@dimen/_2sdp"
            android:layout_marginEnd="@dimen/_4sdp"
            android:ellipsize="end"
            android:fontFamily="@font/montserrat_light"
            android:maxLines="1"
            android:text="@{basketData.offers.offerTermsAndConditions}"
            android:textColor="@color/black"
            android:textSize="@dimen/_9ssp"
            app:layout_constraintBottom_toTopOf="@+id/txtValidTill"
            app:layout_constraintEnd_toStartOf="@+id/txtOffValue"
            app:layout_constraintHorizontal_bias="0.5"
            app:layout_constraintStart_toEndOf="@+id/imgProduct"
            app:layout_constraintTop_toBottomOf="@+id/txtProductName"
            tools:text="Only on Hot subs" />

        <com.google.android.material.textview.MaterialTextView
            android:id="@+id/txtValidTill"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginStart="@dimen/_8sdp"
            android:layout_marginTop="@dimen/_2sdp"
            android:ellipsize="end"
            android:fontFamily="@font/montserrat_medium"
            android:maxLines="1"
            android:text="@string/valid_till"
            android:textColor="@color/black"
            android:textSize="@dimen/_9ssp"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintStart_toEndOf="@+id/imgProduct"
            app:layout_constraintTop_toBottomOf="@+id/txtValidOn" />

        <com.google.android.material.textview.MaterialTextView
            android:id="@+id/txtValidTillDate"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_marginStart="@dimen/_4sdp"
            android:layout_marginEnd="@dimen/_8sdp"
            android:ellipsize="end"
            android:fontFamily="@font/montserrat_medium"
            android:maxLines="1"
            android:text="@{basketData.offers.offerExpiryDate}"
            android:textColor="@color/orange_f87733"
            android:textSize="@dimen/_9ssp"
            app:layout_constraintBottom_toBottomOf="@id/txtValidTill"
            app:layout_constraintEnd_toStartOf="@id/ibDelete"
            app:layout_constraintStart_toEndOf="@+id/txtValidTill"
            app:layout_constraintTop_toTopOf="@id/txtValidTill"
            tools:text="9th Oct" />

        <com.google.android.material.textview.MaterialTextView
            android:id="@+id/txtOffValue"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginEnd="@dimen/_4sdp"
            android:fontFamily="@font/montserrat_bold"
            android:text="@{basketData.offers.lmOfferValue +``+basketData.offers.lmOfferType}"
            android:textColor="@color/blue_2d3263"
            android:textSize="@dimen/_15ssp"
            app:layout_constraintBottom_toBottomOf="@+id/txtProductName"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toEndOf="@+id/txtProductName"
            app:layout_constraintTop_toTopOf="@+id/txtProductName"
            tools:text="15 %" />

        <androidx.appcompat.widget.AppCompatImageButton
            android:id="@+id/ibDelete"
            android:layout_width="@dimen/_30sdp"
            android:layout_height="@dimen/_30sdp"
            android:background="?attr/selectableItemBackgroundBorderless"
            android:backgroundTint="@color/transparent"
            android:clickable="true"
            android:focusable="true"
            android:src="@drawable/ic_delete_basket_item"
            app:layout_constraintBottom_toBottomOf="@+id/txtValidTillDate"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toEndOf="@+id/txtValidTillDate"
            app:layout_constraintTop_toTopOf="@+id/txtValidTillDate" />

    </androidx.constraintlayout.widget.ConstraintLayout>

</com.google.android.material.card.MaterialCardView>
Related