Recyler view listitem image onclick - android

I am working on xamarin android apps. I used recycler view for displaying the images in each row. Now for each item image there is some link which I need to redirect. How can I achieve this onclick action for each image in recycler view.
Please help me in this regard.
Thanks

When creating a recycler view, you need to create a RecyclerView adapter which (among other things) implements methods for creating and binding a viewholder to the item in the recycler view. Somewhere in your code (oftentimes within this recycler view adapter class), you need to define the viewholder that you will use for your recyclerview items. This is where you should assign the onClickListener to your imageView.
Here is an example of a viewholder definition that I think may help you:
public class YourViewHolder extends RecyclerView.ViewHolder {
protected ImageView yourImage;
public YourViewHolder(View v) {
super(v);
final View theView = v;
yourImage = (ImageView) v.findViewById(R.id.yourImage);
yourImage.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
// image clicked... do something
}
});
}
}
Let me know if you need more information on how to set up the recycler view adapter class (I have assumed that you already have done this, but I could be mistaken).

Related

Why is it suggested to attach the onClickListener to the ViewHolder?

I don't see why it is effective to apply the listener to the holder.
I spent much of the day looking at articles. The topics here on stackoverflow covered the range well.
The choices I found:
Attach to TextView - creates multiple listeners.
Attach to ViewHolder - again creates multiple listeners, unless you create a listener and then use that to attach which you can also do with the TextView.
Attach a onItemTouchListener - a surprisingly complicated way.
What I did not see was just a straight forward implements View.OnClickListener attached to the adapter. If you do this, then generate the one public void onClick(View view), and give the adapter a copy of the RecyclerView and then assign the Adapter (this) as the listener to the item view you have inflated in onCreateViewHolder. Then access the position through the RecyclerView getChildAdapterPosition function. See code snippets.
//create adapter class implementing the on click listener
public class WordListAdapter extends RecyclerView.Adapter<WordListAdapter.WordViewHolder> implements View.OnClickListener {
private final LinkedList<String> mWordList;
private LayoutInflater mInFlater;
private final RecyclerView recyclerView;
//in constructor, pass in RecyclerView created in MainActivity
public WordListAdapter(Context context, LinkedList<String> wordList, RecyclerView rView) {
recyclerView = rView; <----
mInFlater = LayoutInflater.from(context);
this.mWordList = wordList;
}
//implementation of View.OnClickListener makes
#Override
public void onClick(View view) {
//get the position of the item that was clicked
int mPosition = recyclerView.getChildAdapterPosition(view); <----
//other code to do what you want with the list(eg. String element = mWordList.get(mPosition);)
}
//And you set your pointer in the adapter class
#Override
public WordListAdapter.WordViewHolder onCreateViewHolder( #NonNull ViewGroup parent, int viewType) {
View mItemView = mInFlater.inflate(R.layout.wordlist_item, parent, false);
mItemView.setOnClickListener(this); <----
return new WordViewHolder(mItemView, this);
}
It seams to me that this answer is simple, and has the advantage of a single thread on click listener that is all handled in the list adapter.
I guess, I mostly wanted to share my solution on a closed topic but I certainly welcome any suggestions as to why this might not be better. This is actually, my solution to challenge2 in Android fundamentals 04.5 RecyclerView.
The primary reason is is suggested to attach the onClickListener to the view holder as opposed to the adapter itself is because the view is what is being clicked on when a user clicks on an item within the Recyclerview.
The Holder you refer to is a class that contains the view and applying the click listener to this holder allows you to differentiate which view (position / item) is actually being clicked.
It's similar to explaining why you would attach a click listener to the button in a layout versus the entire layout itself. Sure, you could attach the click listener to the entire layout, but a user might intend to click on something else in your view as opposed to the button and you would have no way of distinguishing which one was clicked since your clickListener does not help to identify which.

Recycler View edit mode needs to implement two itemClickListener in the same itemview: one for each mode's state

I have an activity which contain a recycler view, in this activity is implemented the edit mode like a lot of applications. everythings works well but I have some performance issue and i'am tryng to goes more deep in the pest practices.
User goes in edit mode by select a menuItem in the toolbar which is placed in the activity, so in the menuItemClickListener in the activity I call a method of the adapter which is used to tell him that user want to go in edit mode:
mAdapter.setEditMode(true);
then in the adapter:
public void setEditMode(boolean editMode){
this.editMode = editMode;
notifyDataSetChanged(); //in order to change the items layout
}
Now the most difficult part: I need to change the itemClickListener when the editMode variable is set to true, so the listener associated with the holder's itemView change dinamically. I am doing this think in onBindViewHolder so I can set the right listener when the edit mode variable change.
#Override
public void onBindViewHolder(RecyclerView.ViewHolder holder,int position) {
if(editMode){
holder.itemView.setOnClickListener(listener1);
}
else{
holder.itemView.setOnClickListener(listener2);
}
}
this solution works but I know that placing a listener inside onBindViewHolder method is a bad practice so I would like to find a solution that allows to implement the listener in the viewHolder constructor.
This is not simple because when the editMode variable is changing the viewHolder constructor is not being called, so he can't set the right listener.
are there any best practice to do this?
After scouring various StackOverFlow answers regarding the most optimum location for a clickListener, people seem to be divided across multiple implementations. Here is what I know for adding a listener in the ViewHolder.
1. Adapter:
In your Adapter, override the onCreateViewHolder() method
#Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType)
{
View view = LayoutInflater.from(//pass in your args);
ImageView imageview1 = //init your views
TextView textView = //init your views
return new MyViewHolder(view, textView);
}
2. Viewholder:
When you create your Viewholder class, allow it to implement View.OnClickListener and override the onClick method there.
public static class MyViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
public ImageView imageView1;
private MyViewHolder(View itemView, ImageView imageView) {
super(itemView);
itemView.setOnClickListener(this);
imageView1 = imageView;
}
#Override
public void onClick(View view) {
//Implement your click functionality here
}
}

Why does OnClickListener on a ViewHolder don't work?

I'm trying to implement a way to handle item selection on a RecyclerView. I personally don't like the way suggested in some answers on SO of passing through gestures, and I thought that implementing an OnClickListener, as suggested here and here, was waaay cleaner.
The fact is that... this pattern doesn't actually work! I'm really not able to understand why my OnClickListener.onClick is never called. It's kinda like another method intercepts the click before onClick can take care of it.
This is my code:
public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
TextView tvName;
ImageView star;
public ViewHolder(View itemView) {
super(itemView);
tvName = (TextView) itemView.findViewById(R.id.CHAT_ITEM_name);
star = (ImageView) itemView.findViewById(R.id.CHAT_ITEM_star);
Fonts.setTypeface(tvName, regular);
}
#Override
public void onClick(View view) {
int position = getLayoutPosition();
select(position);
}
}
Unfortunately it's very important for me to able to access the position of the clicked item in the whole dataset, in order to remove it, so doing something like indexOfChild isn't acceptable too: I tried, but this method gives you the position of the item in the visibile part of the list, thus making list.remove(position) impossible.
Looking at the updated code: you are not setting the onClickListener to any of the views in the ViewHolder. It is an understandable mistake to forget the click listener.
Just use:
tvName.setOnClickListener(this);
star.setOnClickListener(this);
You can set to both or just one of them. You can also simply get the parent layout of these two views, so that the whole item itself in the adapter can be clickable.
itemView.setOnClickListener(this);
You can do it in your onBindViewHolder
#Override
public void onBindViewHolder(ReportViewHolder holder, int position {
holder.itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View arg0) {
// handle your click here.
} });
}
Simplely Click Handler your ViewHolder. Recycler View don't have special attaching click handlers like ListView which has the method setOnItemClickListener().
** public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener
** in public ViewHolder(Context context, View itemView) set public void onClick(View view)
** get position by: int position = getLayoutPosition(); User user = users.get(position);

Create CardView with dynamic custom list inside

I create a RecyclerView with CardViews in my app. Now I want to add inside each CardView a new List of custom Views, with a custom layout (see example Image). When the add button is pressed, there should be insert a new row of this layout inside the card.
How do I realize that? In the internet I readed, that a ListView inside the CardView is not possible, because a ListView is scrollable, and there should not be two scrollable Views on the activity (thats what I found..)
the red marked row is the custom row.
for the RecylcerView I used the ViewHolder, CustomAdapter, etc.
Do I need this for the rows inside to? or is there a simpler way?
What I would do is attached a click handler to the Views is your ViewHolder. In this event handler you can delegate to a presenter of some sort that will add/remove/edit the View in the card holder.
private class MyHolder extends ViewHolder
implements View.OnClickListener {
...
public MyHolder(View itemView, MyPresenter presenter) {
super(itemView);
itemView.setOnClickListener(this);
...
}
#Override
public void onClick(View v) {
presenter.addRow(v);
}
}

How to perform programmatic click on a item in a RecyclerView?

Hi I have a app that uses a Recycler view to display a bunch of items. Now I want to run an android test on the list but I don't know how to set a programmatic click on a given item. Can anyone tell me how to achieve this?
You have to implement it from scratch. The RecyclerView lacks for some of the awesome features that a ListView provides by default. Given this, in the adapter you have to declare an interface for the Observer between Fragment/Activity and the RecyclerView.
The correct method to attach this click event is onBindViewHolder. Then in the adapter you keep the reference to the CustomListener or the View.OnClickListener.
Here is a quick example on how to do this:
#Override
public void onBindViewHolder(SearchListAdapter.ViewHolder holder, final int position) {
//Item clicked
holder.mParent.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//Select or deselect
mListener.notify(holder, position);
}
});
}
And the ViewHolder should be like:
public class ViewHolder extends RecyclerView.ViewHolder {
private View mParent;
public ViewHolder(View itemView) {
super(itemView);
mParent = itemView;
}
}
Where mParent is the current row View.

Categories

Resources