I know it might be a silly question but I need to know after I implement this code:
recyclerView.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
return false;
}
});
Why the recyclerView
is still scrolling when the listener
returns false
? Or more precisely where is the scrolling behavior processed and handled?
I know that return true
means the touch event is consumed and false
means the touch event should get passed to the next view
in view hierarchy. In my mind (which is possibly wrong), the return type shouldn't change the view
behavior. Because when you don't process the onTouchListener
, it means no touch event (including scrolling behavior) is processed so the recyclerView
shouldn't be scrolling no matter the return type is true
or false
. What is wrong in my perception? I hope I'm clear enough.
I know that return true means the touch event is consumed and false means the touch event should get passed to the next view in view hierarchy
This is not true, the correct order when a View
handle a touch event is:
View.dispatchTouchEvent()
will be called first
Sends event to View.OnTouchListener.onTouch()
if exits
If not consumed, process View.onTouchEvent()
In your case because your return false
in View.OnTouchListener.onTouch()
, it means you do not consume the event, so the event will be routed to View.onTouchEvent()
of RecyclerView
, which explains why the RecyclerView
is still scrolling.
Solution 1
Return true
in View.onTouchListener.onTouch()
to show that the RecyclerView
will consume all touch events.
recyclerView.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
// I will consume all touch events,
// so View.onTouchEvent() will not be called.
return true;
}
});
Solution 2
Create a sub-class that extends from RecyclerView
and return false
in View.onTouchEvent()
to show that the RecyclerView
don't show interested in any touch event.
public class MyRecyclerView extends RecyclerView {
public MyRecyclerView(@NonNull Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
}
@Override
public boolean onTouchEvent(MotionEvent e) {
// I don't show interested in any touch event.
return false;
}
}
This is a great presentation about Android Touch System, you should take a look.