Outer Recyclerview not receiving scroll events of

2019-01-24 07:56发布

问题:

I followed this tutorial to implement the behaviors for both hiding the toolbar and the FAB when scrolled: https://mzgreen.github.io/2015/06/23/How-to-hideshow-Toolbar-when-list-is-scrolling(part3)/

I have pasted a demo of what the behavior looks like below.

Now instead of those individual items within the recyclerview in the tabs holding just a textView, I have coded it so that they hold a picture (ImageView) and below it, a recyclerview showing a list of items.

Hence, there is an outer recyclerview that contains a list of inner recyclerviews.

The inner recyclerview does not scroll - I disabled it by following the answer in this thread by overriding the method canScrollVertically(): Disable Scrolling in child Recyclerview android. I also tried enabling the scrolling for the inner recyclerview, but I experienced the same problem.

The outer recyclerview does scroll and has the behavior that shows/hides the toolbar and the FAB.

When I scroll by holding onto the picture (ImageView), the app behavior works perfectly fine, showing and hiding the toolbar and FAB. However, when I have my finger on the inner recyclerview to scroll, the outer recyclerview scrolls and the list moves up and down, but the behavior of show/hiding the toolbar and FAB is never activated.

I have a feeling that this is because the inner recyclerview had intercepted the scroll and the outer recyclerview did not get the scroll event to activate the behavior.

Does anyone know how to make sure the outer recyclerview also gets the scroll event so that the behavior works?

回答1:

Hank Moody comment actually lead me to the correct answer - thanks Hank!

This is how I solved my problem:

  1. Create a 'Scroll Through' recyclerview where the parent will receive all the scroll events of the child by doing this:

    public class ScrollThroughRecyclerView extends RecyclerView {
        public ScrollThroughRecyclerView(Context context) {
            super(context);
        }
    
        public ScrollThroughRecyclerView(Context context, AttributeSet attrs) {
            super(context, attrs);
        }
    
        public ScrollThroughRecyclerView(Context context, AttributeSet attrs, int defStyle) {
            super(context, attrs, defStyle);
        }
    
        @Override
        public boolean dispatchTouchEvent(MotionEvent ev){
            //true - block scrolling of child and allow scrolling for parent recycler
            return true;
        }
    }
    
  2. Use this custom recyclerview in your xml or in your java code and the scroll events will be passed correctly to your parent recyclerview which will activate the app scrollbehavior.



回答2:

if you want put one vertical recycler in another vertical you must set fixed height for child recycler view, or try to overwrite this method

@Override
public boolean dispatchTouchEvent(MotionEvent ev){
    //false - block scrolling of parent recycler and allow scrolling for child
    return false;
}


回答3:

Have you tried using the following in the xml of the inner recyclerview?

app:layout_behavior="@string/appbar_scrolling_view_behavior"

EDIT: assuming you are using CoordinatorLayout.