RecyclerView 移除或解除附加事件
RecyclerView remove or deattach event
对于这个简单问题,我非常感谢您的帮助和指导。
RecyclerView layout
我有一个包含电影列表的 RecyclerView。我想创建一个动态列表,可以从目录中添加一些电影。
问题是,当我为按钮单击添加事件时,由于 holder 被绑定了几次,所以该事件被附加了几次。我不知道如何使用 SetOnClickListener 技术,因为我需要 holder.AdapterPosition 来知道应该在哪里添加新项目。我将它作为附加项传递给 MovieCatalogActivity,然后将其发送回包含 RecyclerView 的 activity。
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);
}
}
}
也许如果我从 ViewHolder 内部监听事件,但我找不到示例。
如果想在item布局中点击Button时添加新的Item,可以参考下面的代码:
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
是我的物品型号,你可以换成你的)
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();
}
}
注:
imAddAfter
以类似的方式实现。
如果您想 return position
到您的 activity,您可以在 RecyclerView.Adapter 中添加一个 EventHandler
(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);
}
并且在方法中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;
}
在你的 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);
}
在您的 activity 中,添加以下代码:
// 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);
}
对于这个简单问题,我非常感谢您的帮助和指导。
RecyclerView layout
我有一个包含电影列表的 RecyclerView。我想创建一个动态列表,可以从目录中添加一些电影。
问题是,当我为按钮单击添加事件时,由于 holder 被绑定了几次,所以该事件被附加了几次。我不知道如何使用 SetOnClickListener 技术,因为我需要 holder.AdapterPosition 来知道应该在哪里添加新项目。我将它作为附加项传递给 MovieCatalogActivity,然后将其发送回包含 RecyclerView 的 activity。
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);
}
}
}
也许如果我从 ViewHolder 内部监听事件,但我找不到示例。
如果想在item布局中点击Button时添加新的Item,可以参考下面的代码:
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
是我的物品型号,你可以换成你的)
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();
}
}
注:
imAddAfter
以类似的方式实现。
如果您想 return position
到您的 activity,您可以在 RecyclerView.Adapter 中添加一个 EventHandler
(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);
}
并且在方法中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;
}
在你的 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);
}
在您的 activity 中,添加以下代码:
// 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);
}