Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

RecyclerView items clicking while scrolling

I have a RecyclerView. Inside its adapter's onBindViewHolder() I set the OnClickListener to the ViewHolder's root layout.

However, I've recently noticed that I can't click on the RecyclerView's items while it's being scrolled. Only after it's stopped. If I click somewhere on the RecyclerView while I'm scrolling it, the RecyclerView only stops at that position, no items are clicked.

You can see what I mean inside the Gmail app. You can't open any email while you are scrolling its RecyclerView.

However, the Google Play app behaves differently. You can open app pages while scrolling the lists of apps. You can even scroll inner RecyclerViews horizontally while the parent RecyclerView is being scrolled.

Also I've noticed the same behaviour for a ScrollView. For example, if you put a lot of buttons inside it and begin to scroll it, the button listeners are not triggered. They can be triggered only after the ScrollView is stopped completely.

Do you have any idea how it's possible to achieve the behaviour like in the Google Play app? Thank you!

like image 642
Sergey Avatar asked Sep 29 '17 17:09

Sergey


2 Answers

Here's a code written by Kimi Chiu in a related question:

@Override
public boolean onInterceptTouchEvent(MotionEvent event) {
    boolean requestCancelDisallowInterceptTouchEvent = getScrollState() == SCROLL_STATE_SETTLING;
    boolean consumed = super.onInterceptTouchEvent(event);
    final int action = event.getActionMasked();

    switch (action) {
        case MotionEvent.ACTION_DOWN:
            if( requestCancelDisallowInterceptTouchEvent ){
                getParent().requestDisallowInterceptTouchEvent(false);
                // stop scroll to enable child view get the touch event
                stopScroll();
                // not consume the event
                return false;
            }
            break;
    }

    return consumed;
}

If you subclass the RecyclerView class and override this method, it will behave as in the question.

like image 137
Sergey Avatar answered Nov 23 '22 05:11

Sergey


Don't do this. Think about the user experience. You want to be able to allow users to scroll without them accidentally clicking to open new windows or details. Android users expect scrolling to prevent clicking. Once you stop, then you expect clicking to show details. You can certainly accomplish this if you want by overriding the onTouch and deciding how to handle the touch event if it is supplied to the recycler view or the row items, but I think you are creating a bad user experience. I tried the app store, it stops when you touch it as well Not sure what you meant by scrolling while open click or horizontal scroll because if I scroll vertically and then swipe left it just changes the page viewer.

So maybe not the answer you want, but I think User Experience is more important than "cool effect of touch while scrolling" management. If Android wanted that to be their OS experience it would be built in. Now this isn't the case for everything like swipable row items, but default master detail list handling is pretty standardized.

like image 22
Sam Avatar answered Nov 23 '22 03:11

Sam