For RecyclerView
if it has not any item, then click on RecyclerView
works,
but if it has items clicking on RecyclerView
doesn't work.
Be careful I mean click on just RecyclerView
not RecyclerView
's item
recyclerView.setOnClickListener(view -> {Timber.d("recyclerView clicked");});
How I can set RecyclerView
clickable even it has items on it.
Try to extend RecyclerView
and Override onInterceptTouchEvent
. Also make it always return true. Then use OnTouch
instead of OnClickListener
Here are some of code.
public class MyRecyclerView extends RecyclerView {
public MyRecyclerView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
}
@Override
public boolean onInterceptTouchEvent(MotionEvent e) {
return true;
}
}
Activity.class
recyclerView.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
Toast.makeText(MainActivity.this,"RecyclerView",Toast.LENGTH_SHORT).show();
return false;
}
});
TL;DR Java
recyclerView.setOnTouchListener(new OnTouchListener() {
@Override
public boolean onTouch(View view, MotionEvent motionEvent) {
if (motionEvent.getAction() == MotionEvent.ACTION_UP)
return view.performClick();
else
return false;
}
});
recyclerView.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View view) {
// do something
}
});
TL;DR Kotlin
recyclerView.setOnTouchListener { view, motionEvent ->
if (motionEvent.action == MotionEvent.ACTION_UP)
view.performClick()
else
false
}
recyclerView.setOnClickListener { view ->
// do something
}
Explanation (Java)
When the user touches the screen, the OnTouchListener
of the topmost view is triggered. Its purpose is to detect gestures (tap, long tap, swipe, etc.) and call the respective handlers. A simple tap, for example, should result in a call to the OnClickListener
.
Now, for some reason, RecyclerView
does not do that (at least it does not watch for the tap gesture) - maybe because the developers did not intend the RecyclerView
to be tapped as a whole.
So, we implement the OnTouchListener
ourselves. The easiest way would be implementing the click logic in the OnTouchListener
itself and return true
to keep the event from propagating further up in the view hierarchy:
recyclerView.setOnTouchListener(new OnTouchListener() {
@Override
public boolean onTouch(View view, MotionEvent motionEvent) {
// do something
return true
}
});
However, as the OnTouchListener
is usually invoked multiple times during a single tap on the screen, we should run our code only once after the last touch event. Furthermore, the business logic should go into the OnClickListener
which is called by performClick()
(that returns true
afterwards):
recyclerView.setOnTouchListener(new OnTouchListener() {
@Override
public boolean onTouch(View view, MotionEvent motionEvent) {
if (motionEvent.getAction() == MotionEvent.ACTION_UP)
return view.performClick();
else
return false;
}
});
recyclerView.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View view) {
// do something
}
});
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With