RecyclerView onClick
Solution 1
As the API's have radically changed, It wouldn't surprise me if you were to create an OnClickListener
for each item. It isn't that much of a hassle though. In your implementation of RecyclerView.Adapter<MyViewHolder>
, you should have:
private final OnClickListener mOnClickListener = new MyOnClickListener();
@Override
public MyViewHolder onCreateViewHolder(final ViewGroup parent, final int viewType) {
View view = LayoutInflater.from(mContext).inflate(R.layout.myview, parent, false);
view.setOnClickListener(mOnClickListener);
return new MyViewHolder(view);
}
The onClick
method:
@Override
public void onClick(final View view) {
int itemPosition = mRecyclerView.getChildLayoutPosition(view);
String item = mList.get(itemPosition);
Toast.makeText(mContext, item, Toast.LENGTH_LONG).show();
}
Solution 2
Here is a better and less tightly coupled way to implement an OnClickListener
for a RecyclerView
.
Snippet of usage:
RecyclerView recyclerView = findViewById(R.id.recycler);
recyclerView.addOnItemTouchListener(
new RecyclerItemClickListener(context, recyclerView ,new RecyclerItemClickListener.OnItemClickListener() {
@Override public void onItemClick(View view, int position) {
// do whatever
}
@Override public void onLongItemClick(View view, int position) {
// do whatever
}
})
);
RecyclerItemClickListener
implementation:
import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.View;
public class RecyclerItemClickListener implements RecyclerView.OnItemTouchListener {
private OnItemClickListener mListener;
public interface OnItemClickListener {
public void onItemClick(View view, int position);
public void onLongItemClick(View view, int position);
}
GestureDetector mGestureDetector;
public RecyclerItemClickListener(Context context, final RecyclerView recyclerView, OnItemClickListener listener) {
mListener = listener;
mGestureDetector = new GestureDetector(context, new GestureDetector.SimpleOnGestureListener() {
@Override
public boolean onSingleTapUp(MotionEvent e) {
return true;
}
@Override
public void onLongPress(MotionEvent e) {
View child = recyclerView.findChildViewUnder(e.getX(), e.getY());
if (child != null && mListener != null) {
mListener.onLongItemClick(child, recyclerView.getChildAdapterPosition(child));
}
}
});
}
@Override public boolean onInterceptTouchEvent(RecyclerView view, MotionEvent e) {
View childView = view.findChildViewUnder(e.getX(), e.getY());
if (childView != null && mListener != null && mGestureDetector.onTouchEvent(e)) {
mListener.onItemClick(childView, view.getChildAdapterPosition(childView));
return true;
}
return false;
}
@Override public void onTouchEvent(RecyclerView view, MotionEvent motionEvent) { }
@Override
public void onRequestDisallowInterceptTouchEvent (boolean disallowIntercept){}
}
Solution 3
I do it in this way, without undue classes, detectors etc. Simple code inside our adapter. Especially better solution for longClick than presented before.
public class PasswordAdapter extends RecyclerView.Adapter<PasswordAdapter.ViewHolder> {
private static ClickListener clickListener;
public static class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener, View.OnLongClickListener {
TextView name;
public ViewHolder(View itemView) {
super(itemView);
itemView.setOnClickListener(this);
itemView.setOnLongClickListener(this);
name = (TextView) itemView.findViewById(R.id.card_name);
}
@Override
public void onClick(View v) {
clickListener.onItemClick(getAdapterPosition(), v);
}
@Override
public boolean onLongClick(View v) {
clickListener.onItemLongClick(getAdapterPosition(), v);
return false;
}
}
public void setOnItemClickListener(ClickListener clickListener) {
PasswordAdapter.clickListener = clickListener;
}
public interface ClickListener {
void onItemClick(int position, View v);
void onItemLongClick(int position, View v);
}
}
Then inside fragment or activity, just hit:
PasswordAdapter mAdapter = ...;
mAdapter.setOnItemClickListener(new PasswordAdapter.ClickListener() {
@Override
public void onItemClick(int position, View v) {
Log.d(TAG, "onItemClick position: " + position);
}
@Override
public void onItemLongClick(int position, View v) {
Log.d(TAG, "onItemLongClick pos = " + position);
}
});
Solution 4
Check out a similar question @CommonsWare's comment links to this, which implements the OnClickListener
interface in the viewHolder
.
Here's a simple example of the ViewHolder
:
TextView textView;//declare global with in adapter class
public static class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
private ViewHolder(View itemView) {
super(itemView);
itemView.setOnClickListener(this);
textView = (TextView)view.findViewById(android.R.id.text1);
}
@Override
public void onClick(View view) {
Toast.makeText(view.getContext(), "position = " + getLayoutPosition(), Toast.LENGTH_SHORT).show();
//go through each item if you have few items within recycler view
if(getLayoutPosition()==0){
//Do whatever you want here
}else if(getLayoutPosition()==1){
//Do whatever you want here
}else if(getLayoutPosition()==2){
}else if(getLayoutPosition()==3){
}else if(getLayoutPosition()==4){
}else if(getLayoutPosition()==5){
}
//or you can use For loop if you have long list of items. Use its length or size of the list as
for(int i = 0; i<exampleList.size(); i++){
}
}
}
The Adapter
then looks like this:
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view =LayoutInflater.from(parent.getContext()).inflate(android.R.layout.simple_list_item_1, parent, false);
return new ViewHolder(view);
}
Solution 5
Based on Jacob Tabak's answer (+1 for him), I was able to add onLongClick listener:
import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.View;
public class RecyclerItemClickListener implements RecyclerView.OnItemTouchListener {
public interface OnItemClickListener {
void onItemClick(View view, int position);
void onItemLongClick(View view, int position);
}
private OnItemClickListener mListener;
private GestureDetector mGestureDetector;
public RecyclerItemClickListener(Context context, final RecyclerView recyclerView, OnItemClickListener listener) {
mListener = listener;
mGestureDetector = new GestureDetector(context, new GestureDetector.SimpleOnGestureListener() {
@Override
public boolean onSingleTapUp(MotionEvent e) {
return true;
}
@Override
public void onLongPress(MotionEvent e) {
View childView = recyclerView.findChildViewUnder(e.getX(), e.getY());
if (childView != null && mListener != null) {
mListener.onItemLongClick(childView, recyclerView.getChildAdapterPosition(childView));
}
}
});
}
@Override
public boolean onInterceptTouchEvent(RecyclerView view, MotionEvent e) {
View childView = view.findChildViewUnder(e.getX(), e.getY());
if (childView != null && mListener != null && mGestureDetector.onTouchEvent(e)) {
mListener.onItemClick(childView, view.getChildAdapterPosition(childView));
}
return false;
}
@Override
public void onTouchEvent(RecyclerView view, MotionEvent motionEvent) {
}
@Override
public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) {
}
}
Then you can use it like this:
recyclerView.addOnItemTouchListener(new RecyclerItemClickListener(getActivity(), recyclerView, new RecyclerItemClickListener.OnItemClickListener() {
@Override
public void onItemClick(View view, int position) {
// ...
}
@Override
public void onItemLongClick(View view, int position) {
// ...
}
}));
![Admin](/assets/logo_square_200-5d0d61d6853298bd2a4fe063103715b4daf2819fc21225efa21dfb93e61952ea.png)
Admin
Updated on January 16, 2021Comments
-
Admin over 3 years
Has anyone using
RecyclerView
found a way to set anonClickListener
to items in theRecyclerView
? I thought of setting a listener to each of the layouts for each item but that seems a little too much hassle I'm sure there is a way for theRecyclerView
to listen for theonClick
event but I can't quite figure it out. -
ian.shaun.thomas over 9 yearsThis seems to go the wrong direction though. If you need to re-use a recyclerview in another fragment/activity, the adapter/viewholder are now defining the logic of the clicks instead of whatever is containing them. The clicks should really be handled directly or indirectly by the containing instance. It seems that a touch listener is the only effective way to go about this.
-
NT_ over 9 yearsThis will not provide any clue about which button or view (within the item) was clicked. But for overall item click, this is fine.
-
Piyush Kukadiya over 9 yearswhat if i want to delete a row on its click ?
-
Piyush Kukadiya over 9 yearswhat if i want to delete a row on its click ?
-
Jacob Tabak over 9 yearsYou should have no issue deleting a row on click. The OnItemClickListener gives you the position of the view in the adapter so you can delete it.
-
Matthias Loibl over 9 yearsOf all the versions I tried, this is the one I got working. But is it ok, to do it that way? Or is there a better way, like best practice?
-
Fifer Sheep over 9 yearsAs far as I could tell, this was the only way. Check this out for more details! stackoverflow.com/a/24933117/1508887
-
Jacob Tabak over 9 yearsngen's comment is correct - if you want to attach an onClick listener to a specific item within the item view, you should probably do that in your adapter, in onBindViewHolder, or in your viewholder itself.
-
Gak2 over 9 yearsOne problem with this method is when you are doing something that takes a few hundred milliseconds like starting an activity. When the item is clicked, and it has a clicked animation there is a noticeable delay between clicking and seeing the animation.
-
Diffy over 9 yearsCan someone please explain the role of mGestureDetector.onTouchEvent(e) here and how it helps in determining the click?
-
wasyl over 9 yearsThis solution feels extremely clunky, there's some delay when processing the 'click' and the feel isn't just ok
-
hash over 9 yearsHow can i open new fragment from inside onclick method?
-
Andrew Orobator over 9 yearsWhy is your code in OnInterceptTouchEvent instead of OnTouchEvent?
-
Lo-Tan over 9 yearsI like this answer better than the one you linked. Who wants to write a gesture listener and hit box detection to handle this. Google--
-
EpicPandaForce about 9 years@tencent I don't see how that is the problem. If the ViewHolder itself contains all information in regards to what data is selected when the element itself is clicked, then the only responsibility of the container is the display of N elements, rather than that of handling the selection of a specific i-th element out of the N elements. The
ListView
was already problematic if you had to create a list of more complicated objects than just simple rows. What if you need to handle different events depending on where you click the item in the ListView? You're screwed. Here, you have each listeners. -
Jigar about 9 yearsgetChildPosition(view) is deprecated method
-
Jigar about 9 yearswe can use getChildLayoutPosition(view) instead.
-
Cris about 9 yearsSorry, how do I use the
setItemChecked(position)
with your implementation? -
leafcutter about 9 yearsThis approach worked well for me - it means you can handle clicks in the activity rather than inside the grid view
-
Raghunandan about 9 years@JacobTabak can we handle both click on individual views in adapter and item click listener. The touch is intercepted by onTouchListener. If i have both then i have both fire listeners one on view and the other on the row item
-
Arūnas Bedžinskas about 9 years@JacobTabak Note: view.getChildPosition(childView) is deprecated now
-
zacharia about 9 years@JacobTabak currently i add a method onLongPress(MotionEvent e) in the interface & in the GestureDetector i override onLogpress. (@Override public void onLongPress(MotionEvent e) { listener.onLongPress(e); }) i want to pass the child view and position , not the motion event to the listener like onItemClick.... How can i implement that..
-
milosmns about 9 yearsTook me a while to adapt to my app, and align and format code to Java/Android standards, but eventually it worked fine.
-
Victor Odiah about 9 yearsgetChildAdapterPosition(view) is a more reliable option than getChildLayoutPosition(view) getChildLayoutPosition(view) may not be equal to Item's adapter position if there are pending changes in the adapter which have not been reflected to the layout yet.
-
Dominik about 9 yearsCould anyone explain to me why this solution with the GestureDetector is supposed to be a better solution than just using "setOnClickListener" inside of onBindViewHolder() in the adapter to the according element? This way at least I need less code than with the GestureDetector solution. Thanks for an explanation.
-
Jon about 9 yearsHow do you add an animation for the long click?
-
Apurva about 9 yearsWhat do I use instead of view.getChildPosition as it has been depreciated?
-
Vince almost 9 yearsDo you mind telling which classes are your snippets in?
onClick()
, belonging toOnClickListener
can be attached to ANY View. The whole question here is which! Please make an effort, a method is not only identified by a name, but also at least by a class. If you don't say your code is to be added to the adapter, your answer does not really help. -
Ced almost 9 yearsShould the onClick method be in the fragment that holds the RecyclerView ? Because you reference the mRecyclerView in your MyOnClickListener class. Where did you get the reference to that object ?
-
Muhammad Riyaz almost 9 yearsSimply use interfaces to avoid complexity. See gist.github.com/riyazMuhammad/1c7b1f9fa3065aa5a46f
-
D4rWiNS almost 9 yearsin my case holder.itemView.setOnClickListener(..)
-
D4rWiNS almost 9 yearsit is named 'itemView' instead of 'view' in my case, just saying for the beginners, some of them dont understand what are they copying, and can't figure out why doesnt work
-
ingsaurabh almost 9 years@Eng.Fouad click effect is not working by using this, although if we set click listener in adapter click effect works any solution to this
-
Brandon almost 9 yearsWhere can I give you money. 4 hours of searching and then I read your post. Thanks for the time you took to post this.
-
Edward Quixote almost 9 yearsI just found out that this approach raises a fatal performance issue. There's great delay before the user could scroll the list(considering a list of several items). The user has to hold for sometime before scrolling in order for the RecyclerView to scroll, otherwise, it's just responding to the tough events.
-
Edward Quixote almost 9 yearsQuestion: The onBindViewHolder(...) returns an int position. Which position is this in regards to the RecyclerView? Is it the Layout Position or Adapter Position?
-
AdamMc331 almost 9 yearsI agree with @EpicPandaForce on this one. I also came to upvote this answer after reading the section of Commonsware's book on handling clicks in RecyclerViews It has worked great for me so far.
-
rgv almost 9 yearsThis sounds stupid but, does this have any memory or efficiency like issue? Because we are assigning the click listener every time a view is being drawn right?
-
nommer almost 9 yearsinstead of OurAdapter.clickListener i think Marurban means PasswordAdapter.clickListener and instead of TrainingAdapter.ClickListener(), should be PasswordAdapter.ClickListener(). Other than that, great solution Marurban! worked for me
-
Paolo Rotolo almost 9 yearsYou should also override
public void onRequestDisallowInterceptTouchEvent (boolean disallowIntercept){}
-
Rajiev Timal almost 9 yearsgetChildPosition is now deprecated, please see my answer below and gist.github.com/RTimal/ddf4040cfba28b461ec7
-
Rajiev Timal almost 9 yearsgetChildPosition is now deprecated and this does not tell you which view was clicked. Please see my answer below and gist.github.com/RTimal/ddf4040cfba28b461ec7
-
Anjula almost 9 yearsthis method will not show the click effect on that item. Please follow below link plus.google.com/+AnjulaSashika/posts/D9jtomxRyDr
-
Bubunyo Nyavor almost 9 yearsIts the layout position
-
Sir NIkolay Cesar The First almost 9 years@Raghav yes every time view is being bind a new click listener is assigned, but this is the standard flow. But the mOnItemClickListener is created only once for the adapter just the view and its position are different on each item click ;)
-
jwir3 over 8 years+1 for the fact that you specifically pointed out another author's method is less tightly coupled, and linked to it as the first line of your answer.
-
Rashad.Z over 8 yearsonItemClick listener is also being activated on long click.
-
markfknight over 8 yearsThanks, this really helped me understand how to implement OnClickListener Interfaces
-
Renato Probst over 8 yearsThis is the best solution because we usually need a lot of properties from activity/fragment on our onItemClickListener, and theres no sense to call it direct from the viewholder (i would have to create a custom constructor for each adapter). By the way, your code is a little extense, i suggest you to cut it to the most important part (setOnItemClickListener).
-
Francois Dermu over 8 years
getChildPosition(View)
is deprecated. Usepublic int getChildAdapterPosition (View child)
instead. Full documentation here -
Naruto Uzumaki over 8 yearsYou should also override
onRequestDisallowInterceptTouchEvent
event. -
Dmitry over 8 yearsFor some reason it doesn't return a clicked view. In my case I click on a checkbox but given view is something different. The way I check:
view.getId() == R.id.selection
-
Dmitry over 8 yearsFor some reason it doesn't return a clicked view. In my case I click on a checkbox but given view is something different. The way I check:
view.getId() == R.id.selection
-
Dmitry over 8 yearsI figured out the view is a topmost
Layout
for alist_item.xml
. How can I know on which exactlyview
a click was? -
Dmitry over 8 yearsI figured out the view is a topmost
Layout
for alist_item.xml
. How can I know on which exactlyview
a click was? -
Nasz Njoka Sr. over 8 yearsfor me this seem to only apply for the last visible item not the clicked item
-
Nasz Njoka Sr. over 8 yearsgetChildPosition() is decapitated
-
Vikram Singh over 8 yearsgetChildPosition() method is deprecated. Use getChildAdapterPosition(View) or getChildLayoutPosition(View).
-
Vikram Singh over 8 yearsgetChildPosition() method is deprecated. Use getChildAdapterPosition(View) or getChildLayoutPosition(View).
-
Mehul Joisar over 8 years
getChildPosition
is deprecatedgetChildAdapterPosition
will give wrong position when you scroll the view.getChildLayoutPosition
will give correct position. -
veritas over 8 years@JacobTabak why this method is better than attaching onClickListener on individual Items ??
-
GuillermoMP over 8 yearsThis is a common bad practice because it looks way too easy. You are creating a new inner listener each time an object is binded (and each item in a recycler can be bound lots of times) which is bad for a)performance b)garbage collection. Instead you should create ONE listener somewhere (in the viewholder, in the adapter, in the upper fragment or activity) and just add it to the items in the viewholder constructor on in onCreateViewHolder. This has the added complexity of having to figure out which item was clicker, but can be solved easily via tags or adding more info to the holder.
-
Hubert Grzeskowiak about 8 yearsThe whole point of a view holder is for it to hold the references to containing elements. If you use findViewById in onCreateViewHolder you're working around the intentional pattern.
-
devunwired about 8 yearsThis implementation introduces a few awkward edge cases since the touch events are divorced from the view they represent. Among them is click timing. GestureDetector supports long press by default, so a longer click is consumed and never reported—long press should be shut off. Another is the requirement of setting the view's visual clickability separately. This implementation doesn't connect with enabling the view to show this state to the user.
-
Edmond Tamas about 8 yearsThis solution seems the best for me, but how does this differ from @bolot 's answer in therms of performance? He has implemented View.OnClickListener directly on the ViewHolder class, which than spits out the onClick method separately. Which would be the best solution?
-
stuckj about 8 yearsfindViewById is only being used on view holder creation here (hence onCreateViewHolder). The view holder is intended to prevent finding the view every time an item is bound to the holder, not on initial creation.
-
Winster almost 8 yearsI had to use v.setClickListener(this) in ViewHolder constructor to make it work. But longclicklistener is still not working
-
0101100101 almost 8 yearsThis unnecessarily creates a new OnClickListener constantly while scrolling and thus shouldn't be used. Use
getAdapterPosition()
to access the item position from the click listener. -
Bubunyo Nyavor almost 8 years@0101100101 where do you do this.
-
0101100101 almost 8 years@orignMaster
ViewHolder
has that method, so it can be used in any listener there. -
Gilberto Ibarra almost 8 yearsViewHolder must be static for the best performance. this is not a good answer.
-
iYonatan almost 8 yearsWhere MyOnClickListener class should be written?
-
K Neeraj Lal almost 8 years
getPosition()
is deprecated, usegetAdapterPosition()
orgetLayoutPosition()
instead. -
tanghao over 7 years
public MyViewHolder onCreateViewHolder(final ViewGroup parent, final int position)
is confusing. The second argument is viewType instead of position. The position argument is only available inonBindViewHolder(MyViewHolder holder, int position)
-
zholmes1 over 7 yearsWhy are you taking a
Context
as a constructor parameter when you can just userecyclerView.getContext()
? -
ChrisR over 7 yearsIn the ViewHolder Class, when I set the onLongClick to return false, I fire off a longclick and both onItemClick and onItemLongClick get called. When I set the onLongClick to return true, only the correct click gets called, but the adapter doesnt update the recyclerview when I delete an item on a long click. Any Ideas as to what I'm doing wrong?
-
Justin Mitchell over 7 yearsRecyclerView is pretty powerful even though you have to do the legwork yourself to handle the data and deal with any changes. +1 for the answer, perfecto!
-
BladeCoder over 7 yearsAnother reason to avoid the Gesture Detector solution is that it doesn't work with keypad navigation.
-
BladeCoder over 7 yearsThe static clickListener creates a memory leak. Declare the listener as non-static and bind it to the ViewHolder instead.
-
BladeCoder over 7 yearsYou should use getAdapterPosition() instead of getLayoutPosition()
-
Zac over 7 yearsI have a checkbox in the card and when I use this class, for some reason holder.checkbox.setOnCheckedChangeListener does not get called. How to sort of bring the checkbox "to front"?
-
Sumit Jha over 7 years
return true
fromonLongClick
to consume the event and avoid toast appearing for both click and long click. -
W.K.S over 7 yearscontainer should be WeakReference<View>. The Context (your activity) contains a reference to the recycler view, which contains a reference to the view holder which, in this case, has a reference back to the context.
-
Sir NIkolay Cesar The First over 7 years@W.K.S the container is different for each item and is needed to assign the onclick listener to it. The RecyclerView should recycle the ViewHolder if it's needed...
-
Renato over 7 yearsThis solution does not consider focus navigation (keyboard navigation), something that a simple click listener could solve (click listeners encapsulates keyboard enter, D-Pad center, and other pointer events). This solution is not accessible as it can only handle touch events and shouldn't be used. Consider using a simple click listener with
getChildAdapterPosition()
to retrieve position. -
Ajit Kumar Dubey about 7 yearsWhen user click on button which is inside item view, how to handle that event?
-
Nigel Savage about 7 yearsthis is a good simple approach for differentiating the row / item from the sub-items
-
user2695433 about 7 yearsCan you let me know if I had 2 buttons How can I get to know which button is clicked inside the Recyclerview?
-
N Sharma about 7 yearsHow to send
mRecyclerView
in an adapter ? -
Rissmon Suresh almost 7 yearsit's bad practice to implement click listener inside an onCreateView().
-
Marurban almost 7 yearsYou can check its id inside onClick method v.getId()
-
peterkodermac almost 7 yearsCan confirm, this library is great! Very easy to use, good job!
-
Pablo Escobar almost 7 yearsTotal disaster. You'll get the item clicked position of the item which was just blinded not the item you click
-
Mykola Tychyna almost 7 yearsGreat example to kill app performance and create memory overuse! With this example you just need scroll to create hundreds of useless objects, that in a moment will be useless and have to be accessed as garbige. @NoobDogg is right. No ClickListeners haven't to be created at onBindView. A click listener have to be created once in onCreateView (or holder constructor), and exists while we need screen with this adapter.
-
Sir NIkolay Cesar The First over 6 years@MykolaTychyna how will you perform click listener for an item, when you don't have it's position on onCreateView?! You need to know which item was clicked and have it's position so you can access it's data. You are just not right
-
Mykola Tychyna over 6 years@Sir NIkolay Cesar The First please at first notice the problem of creation of huge numbers of objects (ClickListeners) with very short life time. Its overhead and antipattern - always! When you are running onCreateViewHolder your are running ViewHolder constructor, and inside it you have to create click lstener. Inside of method onClick you can call getAdapterPosition and perform with this index get on your data collection. In this case ClickListeners will be created as much as ViewHolders.
-
Trevor over 6 yearsTo get the item position inside onCreateView (so that the click listener may be bound there), you simply need to have another property inside your ViewHolder that captures the index, or some other metadata that provides a 'handle' to that item, during onBindViewHolder. This is all I do. There is no need for repeated binding of listeners, and there is no need to jump through any hoops to calculate the clicked item. I'm absolutely staggered that none of these answers illustrate this.
-
Trevor over 6 yearsBinding the click listener during ViewHolder creation is the correct way as it avoids repeated listener assignments that would happen if you did it in onBindViewHolder. However, the trick being missed here is that I also use ViewHolder to retain an ID (or some other 'handle' metadata) that provides means to determine the clicked item. This is instead of all the pointless jumping through hoops to calculate clicked Item position. So all I do is bind a click listener in the holder ctor, and have the holder also capture meta information that provides a pointer of some sort to the underlying data.
-
Trevor over 6 yearsI find it absolutely staggering that despite this being so simple to do as described above, some of the highest voted answers here advocate use of MotionEvents and various other bloat.
-
Shirish Herwade over 6 yearswhere do this 'onClick' method belongs? How did you get 'mRecyclerView' inside that onClick method?
-
Nick Sikrier over 6 yearsSetting click for any part of view in
RecyclerView.ViewHolder
leads to incorrect processing of touch events. For example, if you would like to implement SnapHelper for such RecyclerView,OnClickListener
will overrideOnTouchListener
in SnapHelper and last one won't receiveMotionEvent.ACTION_DOWN
events. -
Amir Ziarati about 6 yearswhat if the list has one item ? :/ i need recycler view click not item click
-
Amir Ziarati about 6 yearsdoesnt work on a list with one item. its item click rather than recycler click.
-
Nikson about 6 years@nhaarman can you help me to solve this stackoverflow.com/questions/50115252/…
-
Pemba Tamang about 6 yearswhere does this 'onClick' method belong? How did you get 'mRecyclerView' inside that onClick method?...
-
mshsayem about 6 years@PembaTamang @Shirish Herwade You can override the method
onAttachedToRecyclerView()
of your adapter, then you will get a reference to the recyclerView; set it to a member variable saymRecyclerView
. And now, you got it. -
RoCkDevstack about 6 yearsHow to pass the holder values through intent?
-
RoCkDevstack about 6 yearsHow do you pass the
holder
values through intent? -
Kennedy Nyaga about 6 yearsgetAdapterPosition() replaces getPosition()
-
Arslan Maqbool almost 6 yearsits click on the on the whole item. if i have one more button in this to perform functionality on this. it's also treat like as itemview click listener?
-
user1872384 over 5 yearswhy is it so confusing to just add a listener =.='' it's so much easier on iOS... Adding delegate
-
AJW about 5 years@BladeCoder Can you provide an example of how best to bind the clickListener to the ViewHolder? Just assign it to the itemView of the clickListener?
-
BladeCoder about 5 years@AJW The simplest way is to initialize the listener early and pass it as argument to the Adapter constructor and then the ViewHolder constructor.
-
O-9 about 5 yearsthat
mRecyclerView
was bothering me (how do you access it inside adapter-class), so I modified the Adapter constructorAdapter(..., RecyclerView rcv)
to accept the owner RV. Then I am able to access the element's position [inside onClick]final int pos = myAdapter.this.myRecView.getChildAdapterPosition(view);
and it seems to work... -
Sa'ad Abdurrazzaq almost 5 yearsHi mate, can you help me to solve this issue please.. I've been stuck many days here stackoverflow.com/questions/57068321/…
-
nhaarman almost 5 years@Sa'adAbdurrazzaq No, and I'd appreciate it if you wouldn't ping people like this.
-
Roman Gherta over 4 yearsHi Jimmy, the rule was that you should not pass view references to the viewmodel if you don't want memory leaks. In this case we are passing viewmodel to adapter that is managing views. I tried to think of situations under which this would create a memory leak but unfortunately I cannot think of any. VIewmodel lifecycle is larger than adapter and thus I do not think this would create a memory leak. If you have something on your mind, do let me know. I do not claim the absolute truth.
-
Sir NIkolay Cesar The First over 4 yearsOk I editted my answer as I see that some people are still liking it ;)
-
CoolMind over 4 yearsYou need to set
clickListener
with a method or constructor. -
Egor almost 4 yearsI'm listened that it is bad solution because you create too many listeners.
-
Gopal Singh Sirvi almost 4 yearsIt will create as many listeners as many items are visible on the screen. As we scroll the unused listeners will be garbage collected
-
Gopal Singh Sirvi almost 4 yearsOther way is to add a tag to the view, we can use the position number as tag and create only one listener and set it to all items. Then the position will be found out by getting the tag
-
Mr-IDE over 3 yearsThere are some other ways to get a reference to the full list row View, using the ViewHolder: 1 -
ViewGroup rowView = (ViewGroup)viewHolder.imageIV.getParent()
. 2 -View rowView = viewHolder.itemView
. Then you can addonClickListeners
to theserowViews
. -
Hamburg is nice over 3 yearsBecause MANY people asked this: If I understand correctly, the onClick() method is inside the class "MyOnClickListener" he used for the click listener. The reference to mRecyclerView must have been passed as an argument to the constructor or so (which he unfortunately didn't show). please correct me if I'm wrong!
-
Liker777 over 3 yearsThanks, that is even better than the initial answer. Works fine for me
-
Charan over 3 yearsI have the same approach, but an item click is not triggered until a 2-3 extra clicks on the same line item. Any idea why extra clicks are required?
-
Ehsan Rosdi almost 3 yearsThis worked for me. Easier to understand for newbie like me. :) Thanks.
-
Chucky over 2 yearsThis is great. Thanks for bringing it to my attention - I normally trust most practices that come directly from Google. Do you know if the approach is any different when using an MVVM architecture? Also, it appears to be called a Primary/Detail Flow now when creating a new project!
-
Chucky over 2 yearsI gave it a whirl, and it doesn't seem to cause any issue with my MVVM architected app. I use an ItemViewModel as the .tag object of the item view. Not sure if this is best practice but works for me for now.
-
clic over 2 yearsgetAdapterPosition() is deprecated: "This method is confusing when adapters nest other adapters. If you are calling this in the context of an Adapter, you probably want to call getBindingAdapterPosition() or if you want the position as RecyclerView sees it, you should call getAbsoluteAdapterPosition()"
-
clic over 2 yearsgetAdapterPosition() is deprecated: "This method is confusing when adapters nest other adapters. If you are calling this in the context of an Adapter, you probably want to call getBindingAdapterPosition() or if you want the position as RecyclerView sees it, you should call getAbsoluteAdapterPosition()"
-
clic over 2 yearsgetAdapterPosition() is deprecated: "This method is confusing when adapters nest other adapters. If you are calling this in the context of an Adapter, you probably want to call getBindingAdapterPosition() or if you want the position as RecyclerView sees it, you should call getAbsoluteAdapterPosition()"
-
clic over 2 yearsgetAdapterPosition() is deprecated: "This method is confusing when adapters nest other adapters. If you are calling this in the context of an Adapter, you probably want to call getBindingAdapterPosition() or if you want the position as RecyclerView sees it, you should call getAbsoluteAdapterPosition()"
-
clic over 2 yearsgetAdapterPosition() is deprecated: "This method is confusing when adapters nest other adapters. If you are calling this in the context of an Adapter, you probably want to call getBindingAdapterPosition() or if you want the position as RecyclerView sees it, you should call getAbsoluteAdapterPosition()"
-
clic over 2 yearsgetAdapterPosition() is deprecated: "This method is confusing when adapters nest other adapters. If you are calling this in the context of an Adapter, you probably want to call getBindingAdapterPosition() or if you want the position as RecyclerView sees it, you should call getAbsoluteAdapterPosition()"
-
clic over 2 yearsgetAdapterPosition() is deprecated: "This method is confusing when adapters nest other adapters. If you are calling this in the context of an Adapter, you probably want to call getBindingAdapterPosition() or if you want the position as RecyclerView sees it, you should call getAbsoluteAdapterPosition()"
-
clic over 2 yearsgetAdapterPosition() is deprecated: "This method is confusing when adapters nest other adapters. If you are calling this in the context of an Adapter, you probably want to call getBindingAdapterPosition() or if you want the position as RecyclerView sees it, you should call getAbsoluteAdapterPosition()"
-
NightStorm over 2 yearsWhats no position?
-
Gastón Saillén over 2 yearsit's -1, its part of RecyclerView developer.android.com/reference/android/support/v7/widget/…