Search code examples
androidonclicklistenerandroid-recyclerviewandroid-viewholder

Setting onClickListener to the whole item in onBindViewHolder


I have an RecyclerView Adapter and I want to set the onClick to the whole item but this code and when I also tried it with myViewHolder.view.setOnClickListener(..) both still only listened to the click of the checkbox.

How can I set the onClickListener to the whole item ?

public class DeliveryPointSelectionAdapter extends RecyclerView.Adapter<DeliveryPointSelectionAdapter.MyViewHolder> {
    private static final String TAG = MyViewHolder.class.getSimpleName();
    private List<DeliveryPoint> deliveryPointList;

    interface OnItemCheckListener {
        void onItemCheck(DeliveryPoint deliveryPoint);
        void onItemUncheck(DeliveryPoint deliveryPoint);
    }

    @NonNull
    private OnItemCheckListener onItemCheckListener;

    public DeliveryPointSelectionAdapter(List<DeliveryPoint> deliveryPointList, @NonNull OnItemCheckListener onItemCheckListener) {
        this.deliveryPointList = deliveryPointList;
        this.onItemCheckListener = onItemCheckListener;
    }

    @NonNull
    @Override
    public DeliveryPointSelectionAdapter.MyViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int viewType) {
        View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.dialog_select_deliverypoints_to_change_item, viewGroup, false);
        return new MyViewHolder(view);
    }

    @Override
    public void onBindViewHolder(@NonNull MyViewHolder myViewHolder, int i) {
        DeliveryPoint deliveryPoint = deliveryPointList.get(i);
        myViewHolder.tvFormattedString.setText(deliveryPoint.domesticAddress.formattedString);
        myViewHolder.checkBox.setChecked(deliveryPoint.isCheckedForLocationUpdate);

        myViewHolder.linearLayout.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                DeliveryPoint deliveryPoint1 = deliveryPointList.get(myViewHolder.getAdapterPosition());
                if (myViewHolder.checkBox.isChecked()) {
                    deliveryPoint1.setCheckedForLocationUpdate(true);
                    onItemCheckListener.onItemCheck(deliveryPoint1);
                } else {
                    deliveryPoint1.setCheckedForLocationUpdate(false);
                    onItemCheckListener.onItemUncheck(deliveryPoint1);
                }
            }
        });

//        myViewHolder.checkBox.setOnCheckedChangeListener((buttonView, isChecked) -> {
//            DeliveryPoint deliveryPoint1 = deliveryPointList.get(myViewHolder.getAdapterPosition());
//            if (myViewHolder.checkBox.isChecked()) {
//                deliveryPoint1.setCheckedForLocationUpdate(true);
//                onItemCheckListener.onItemCheck(deliveryPoint1);
//            } else {
//                deliveryPoint1.setCheckedForLocationUpdate(false);
//                onItemCheckListener.onItemUncheck(deliveryPoint1);
//            }
//        });
    }

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

    @Override
    public int getItemViewType(int position){
        return position;
    }

    public static class MyViewHolder extends RecyclerView.ViewHolder {
        TextView tvFormattedString;
        CheckBox checkBox;
        LinearLayout linearLayout;
        View view;

        MyViewHolder(View view) {
            super(view);
            tvFormattedString = (TextView) view.findViewById(R.id.tv_formatted_string);
            checkBox = view.findViewById(R.id.cb_deliverypoint_checked);
            linearLayout = view.findViewById(R.id.ll_delivery_points_layout);
            this.view = view;
        }
    }
}

Item View Layout:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/ll_delivery_points_layout"

    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

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

        <CheckBox
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:id="@+id/cb_deliverypoint_checked"/>

        <TextView
            android:id="@+id/tv_formatted_string"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:gravity="center_vertical"
            android:paddingStart="25dp"
            android:paddingTop="15dp"
            android:paddingEnd="25dp"
            android:textColor="@color/gray_text_light"
            android:textSize="18sp"

            tools:ignore="RtlSymmetry" />
    </LinearLayout>
</LinearLayout>

Solution

  • Like other users already mentioned myViewHolder.itemView.setOnClickListener to set onClick on the recyclerView holder. But, correct me if I am wrong, it seems you want your checkbox to be checked/unchecked only by holder click. In that case you need to disable it by adding following codes to your layout xml

                   android:clickable="false"
                   android:focusable="false"
                   android:focusableInTouchMode="false"
    

    Otherwise clicking on checkbox will take its click and not execute the code you wrote for itemview click.

    Since you are setting it to checked based on deliveryPoint.isCheckedForLocationUpdate you can notifyItemChanged(position) to update the holder checkbox after click.

    See if this helps.

    EDIT: Based on the comments if you are actually trying to toggle your checkbox in the view you should use something like this: also if you create a new object deliveryPoint1 no change is made to the original object you have in the view

    myViewHolder.itemView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    if (myViewHolder.checkBox.isChecked()) {
                        deliveryPoint.setCheckedForLocationUpdate(false);
                        onItemCheckListener.onItemUncheck(deliveryPoint);
                    } else {
                        deliveryPoint.setCheckedForLocationUpdate(true);
                        onItemCheckListener.onItemCheck(deliveryPoint);
                    }
                }
            });