Reputation: 45
I have recycler view
I need to open activity by click on element on recycler view
I do it like this in Adapter
public override RecyclerView.ViewHolder OnCreateViewHolder(ViewGroup parent, int viewType)
{
var layout = LayoutInflater.From(parent.Context).Inflate(Resource.Layout.MovieRow, parent, false);
return new MovieViewHolder(layout, OnItemClick);
}
public override int ItemCount
{
get { return movies.Count; }
}
void OnItemClick(int position)
{
if (ItemClick != null)
// _context.StartActivity(typeof(Register));
ItemClick(this, position);
}
And like this on ViewHolder
public MovieViewHolder(View itemView, Action<int> listener) : base(itemView)
{
MovieNameTextView = itemView.FindViewById<TextView>(Resource.Id.movieNameText);
DirectedByTextView = itemView.FindViewById<TextView>(Resource.Id.directedByText);
Image = itemView.FindViewById<ImageView>(Resource.Id.image);
itemView.Click += (s, e) => listener(Position);
}
But when I click on element in Recycler View , nothing happens, where is my problem?
Upvotes: 0
Views: 412
Reputation: 24470
It is a bit unclear what you do with your ItemClick
and how you propagate it up to the surface.
So first of all, in your MovieViewHolder
you want add an EventHandler
to your item view's Click
event, just like you've shown. You should also remember to remove the event subscription again, preferably in Dispose
so that you don't leak memory.
So something like:
public MovieViewHolder(View itemView, ...) : base(itemView)
{
ItemView.Click += OnItemClick;
}
private void OnItemClick(object s, EventArgs e)
{
}
protected override void Dispose(bool disposing)
{
if (disposing)
{
ItemView.Click -= OnItemClick;
}
}
Then I'd probably just use ICommand
like most MVVM frameworks do, to propagate actions.
public ICommand ItemClick
{
get; set;
}
Then in OnItemClick
invoke the command:
private void OnItemClick(object s, EventArgs e)
{
if (ItemClick == null) return;
if (ItemClick.CanExecute(null))
ItemClick.Execute(null);
}
Then in your RecyclerView.Adapter
implementation you would assign the command in OnCreateViewHolder
:
public override RecyclerView.ViewHolder OnCreateViewHolder(ViewGroup parent, int viewType)
{
var vh = new MovieViewHolder(...)
{
Click = ItemClick
};
return vh;
}
Your Adapter would also have a ItemClick
ICommand
property which you set from your View where you create it.
public ICommand ItemClick {get; set;}
In your View:
var recycler = FindViewById<RecyclerView>(...);
var adapter = new MovieAdapter {
ItemClick = ViewModel.ItemClick
};
ViewModel.ItemClick
here is just an instance of your implementation of ICommand
. If you wan't you can change ICommand
to Action
instead or something like that to get a callback instead.
Just keep in mind, if you change the MovieAdapter.ItemClick
after at runtime at a later point, after a bunch of ViewHolder's have been created, you would cause inconsistencies as the old ViewHolder's would be pointing at your old ItemClick.
Upvotes: 1