Mauricio
Mauricio

Reputation: 3

RecyclerView remove or deattach event

I would really appreciate your help and guidance, regarding this simple issue.

RecyclerView layout

I have a RecyclerView that has a list of movies. I would like to create a dynamic list, that can add some movies from a catalog.

The thing is that when I add the event for the button click, since the holder gets binded several times, the event gets attached several times. I do not know how to use the SetOnClickListener tecnique because I need the holder.AdapterPosition to know where should the new item should be added. I pass it as an extra to the MovieCatalogActivity and then send it back to the activity that holds the RecyclerView.

using Android.App;
using Android.Content;
using Android.OS;
using Android.Runtime;
using Android.Views;
using Android.Widget;
using AndroidX.RecyclerView.Widget;
using Java.Util;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Supers.Adapters
{
    public class adap_rv : RecyclerView.Adapter
    {
        public List<ItemMovies> data;
        Context context;
        public adap_rv(List<ItemMovies> listOfMovies, Context _context)
        {
            data = listOfMovies;
            context = _context;
        }

        public override RecyclerView.ViewHolder OnCreateViewHolder(ViewGroup parent, int viewType)
        {
            View itemView = LayoutInflater.From(parent.Context).Inflate(Resource.Layout.elem_ReviewMovies, parent, false);
            ViewHolderRR vh = new ViewHolderRR(itemView);
            return vh;
        }

        public override void OnBindViewHolder(RecyclerView.ViewHolder holder, int position)
        {
            ViewHolderRR vh = holder as ViewHolderRR;


            vh.imAddBefore.Click += delegate
            {
                ShowMovieCatalog(holder.AdapterPosition);
            };
            vh.imAddAfter.Click += delegate
            {
                ShowMovieCatalog(holder.AdapterPosition + 1);
            };


            vh.tvName.Text = data[position].Name;


        }




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


        public void OnItemMove(int fromPosition, int toPosition)
        {
            data.Swap(fromPosition, toPosition);
            NotifyItemMoved(fromPosition, toPosition);

        }

        public void OnItemDismiss(int position)
        {
            data.RemoveAt(position);
            NotifyItemRemoved(position);

        }

        public void AddItem(int position, ItemMovies movie)
        {
            if (position > data.Count)
            {
                data.Add(movie);
            }
            else
            {
                data.Insert(position, movie);
            }

            NotifyItemInserted(position);
        }

        void ShowMovieCatalog(int position)
        {
            Intent intent = new Intent(context, typeof(Act_frmMovieCatalog));
            intent.PutExtra(Enums.INTENTEXTRAS.INT_POSITIONITEM.ToString(), position);
            ((Activity)context).StartActivityForResult(intent, 100);
        }

    }

    public class ViewHolderRR : RecyclerView.ViewHolder
    {
        public TextView tvName { get; private set; }
        public ImageButton imAddBefore { get; private set; }
        public ImageButton imAddAfter { get; private set; }
        public ViewHolderRR(View itemView) : base(itemView)
        {
            imAddBefore = itemView.FindViewById<ImageButton>(Resource.Id.elem_btnAddBefore);
            imAddAfter = itemView.FindViewById<ImageButton>(Resource.Id.elem_btnAddAfter);
        }

    }
}

Maybe if I listen to events from inside the ViewHolder, but I can't find examples.

Upvotes: 0

Views: 377

Answers (1)

Jessie Zhang -MSFT
Jessie Zhang -MSFT

Reputation: 13833

If you want to add new Item when clicking the Button in the item layout, you can refer to the following code:

public override void OnBindViewHolder(RecyclerView.ViewHolder holder, int position)
        {
            ViewHolderRR vh = holder as ViewHolderRR;

           // vh.imAddBefore.Click += delegate
           //{
           //    ShowMovieCatalog(holder.AdapterPosition);
           //};

           // other code

           vh.imAddBefore.SetOnClickListener(new MyAddItemBefore(position));

        }

MyAddItemBefore.cs (Photo is my item model, you can change to yours)

   class MyAddItemBefore : Java.Lang.Object, View.IOnClickListener
    {
        Photo item;
        int position;
        public MyAddItemBefore( int position) {
            this.item=  new Photo();
            this.position = position;
        }

        public void OnClick(View v)
        {
            item.mCaption = "test";
            data.Insert(position, item);

            adapter.NotifyDataSetChanged();
        }
    }

Note:

imAddAfter is implemented in a similar way.

And if you want to return position to your activity, you can add a EventHandler in your RecyclerView.Adapter(adap_rv ).

 public event EventHandler<int> ItemClick;

 // Raise an event when the item-click takes place:
    void OnClick(int position)
    {
        if (ItemClick != null)
            ItemClick(this, position);
    }

And in method OnCreateViewHolder

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

        // pass `OnClick` to Your ViewHolder
        ViewHolderRR vh = new ViewHolderRR(itemView,OnClick);
        return vh;
    }

And in your ViewHolderRR.cs

     public ViewHolderRR(View itemView, Action<int> listener) : base(itemView)
    {
        // other code
        imAddBefore = itemView.FindViewById<Button>(Resource.Id.AddBeforeBtn);

        // Detect user clicks on the item view and report which item
        // was clicked (by layout position) to the listener:
        imAddBefore.Click += (sender, e) => listener(base.LayoutPosition);

 }

In your activity,add the following code:

    // mAdapter is the instance of your RecyclerView.Adapter (`adap_rv `)
    mAdapter.ItemClick += OnItemClick;


    void OnItemClick(object sender, int position)
    {
        int itemNum = position + 1;

        System.Diagnostics.Debug.WriteLine("clicked position = " + itemNum);
    }

Upvotes: 0

Related Questions