Xamarin Android RecyclerView with CardView button clicked multiple times

XiemasXiemas BEMember

I’m trying to make a RecyclerViewwith CardViews. Each CardViewhas multiple (4) buttons. The app runs fine but if I scroll in the RecyclerViewwhen I press the button once it clicks/runs the code multiple times.

I know what the problem is but I can’t solve it. The buttons get delegated multiple times.

So how do I need to delegate my buttons in order to only run them ones even on scroll?

My RecyclerAdapterlooks like this:

        using System;
        using System.Collections.Generic;
        using System.Linq;
        using System.Text;
        using Android.App;
        using Android.Content;
        using Android.OS;
        using Android.Runtime;
        using Android.Views;
        using Android.Widget;
        using Android.Support.V7.Widget;
        using MobileApp.Models;
        using Android.Support.Design.Widget;

        namespace MobileApp
        {
            public class EvenementRecyclerAdapter : RecyclerView.Adapter
            {
                private List<Knop> Knoppen;
                private RecyclerView mRecyclerView;
                private Context mContext;
                private string mEvenementNaam;

                public EvenementRecyclerAdapter(List<Knop> knoppen, RecyclerView recyclerView, Context context, string evenementNaam)
                {
                    Knoppen = knoppen;
                    mRecyclerView = recyclerView;
                    mContext = context;
                    mEvenementNaam = evenementNaam;
                }

                public class MyView : RecyclerView.ViewHolder
                {
                    public View mMainView { get; set; }
                    public TextView mName { get; set; }
                    public TextView mInfo { get; set; }
                    public TextView mSales { get; set; }
                    public Button mBtnOne { get; set; }
                    public Button mBtnTwo { get; set; }
                    public Button mBtnFive { get; set; }
                    public Button mBtnDeleteOne { get; set; }

                    public MyView(View view) : base(view)
                    {
                        mMainView = view;
                    }
                }

                public override RecyclerView.ViewHolder OnCreateViewHolder(ViewGroup parent, int viewType)
                {
                    View row = LayoutInflater.From(parent.Context).Inflate(Resource.Layout.CardKnopEvenement, parent, false);

                    TextView knopNaam = row.FindViewById<TextView>(Resource.Id.knopNaam_cardview);
                    TextView knopInfo = row.FindViewById<TextView>(Resource.Id.knopInfo_cardview);
                    TextView aantalVerkocht = row.FindViewById<TextView>(Resource.Id.aantalVerkocht_cardview);
                    Button buttonOne = row.FindViewById<Button>(Resource.Id.btnOne);
                    Button buttonTwo = row.FindViewById<Button>(Resource.Id.btnTwo);
                    Button buttonFive = row.FindViewById<Button>(Resource.Id.btnFive);
                    Button buttonDeleteone = row.FindViewById<Button>(Resource.Id.btnDeleteOne);

                    MyView view = new MyView(row) { mName = knopNaam, mInfo = knopInfo, mSales = aantalVerkocht, mBtnOne = buttonOne, mBtnTwo = buttonTwo, mBtnFive = buttonFive, mBtnDeleteOne = buttonDeleteone };
                    return view;
                }

                public override void OnBindViewHolder(RecyclerView.ViewHolder holder, int position)
                {
                    MyView myHolder = holder as MyView;
                    myHolder.mMainView.Click += mMainView_Click;
                    myHolder.mName.Text = Knoppen[position].Naam;
                    myHolder.mSales.Text = ConnectionDB.GetVerkochtAantal(mEvenementNaam, myHolder.mName.Text);

                    //Create button click events
                    myHolder.mBtnOne.Click += delegate {
                        Toast.MakeText(mContext, myHolder.mSales.Text, ToastLength.Short).Show();
                    };

                    myHolder.mBtnTwo.Click += delegate {
                        Toast.MakeText(mContext, myHolder.mSales.Text, ToastLength.Short).Show();
                    };

                    myHolder.mBtnFive.Click += delegate {
                        Toast.MakeText(mContext, myHolder.mSales.Text, ToastLength.Short).Show();
                    };

                    myHolder.mBtnDeleteOne.Click += delegate {
                        //Toast.MakeText(mContext, myHolder.mSales.Text, ToastLength.Short).Show();
                    };
                }

                void mMainView_Click(object sender, EventArgs e)
                {
                    int position = mRecyclerView.GetChildAdapterPosition((View)sender);
                }

                public override int ItemCount
                {
                    get { return Knoppen.Count; }
                }
            }
        }

My app design looks like:

I didn't find anything I could use on the internet. Thanks in advance!

Best Answer

Answers

  • GaryParkinGaryParkin USMember ✭✭

    Thank you Xiemas. I didn't have the same issue but I did want to learn how to make a button clickable in a CardView.

  • c0mmanderc0mmander USMember ✭✭

    @Xiemas said:

    EDIT

    I fixed it by putting a if statement around my delegate to check if it had a OnClickListener

    if (!myHolder.mBtnOne.HasOnClickListeners)
                {
                    myHolder.mBtnOne.Click += delegate {
                        Toast.MakeText(mContext, myHolder.mSales.Text, ToastLength.Short).Show();
                    };
                }
    

    Really useful answered, thank you @Xiemas

    if someone wanna have position of item , just in click event add :

    var ItemPosition = mRecyclerView.GetChildPosition((View)myHolder.mMainView);

Sign In or Register to comment.