25

I have a RecyclerView using a LinearLayoutManager with HORIZONTAL orientation, nested inside a FrameLayout using the BottomSheet Behavior.

When attempting to drag vertically across the RecyclerView, the BottomSheet doesn't respond to the drag event. Presumably this is because vertical scrolling is disabled for a LayoutManager with horizontal orientation.

I've tried overriding LinearLayoutManager.canScrollVertically() and returning true. This sort of works.. If you drag vertically in a very careful manner, the BottomSheet will respond. As soon as any horizontal movement is involved however, the BottomSheet stops responding to vertical drag events.

I'm not sure if overriding canScrollVertically() is the right approach here - it certainly doesn't feel right from a UX point of view.

I've also noticed that if I use a ViewPager rather than a RecyclerView with a horizontally oriented LayoutManager, the BottomSheet responds to vertical swipe events as desired.

Is there some other method of LayoutManager, RecyclerView, BottomSheet Behavior, or something else altogether that can help propagate the vertical scroll events on to the BottomSheet Behavior?

There's an example of the problem here:

https://github.com/timusus/bottomsheet-test (Problem can be reproduced with commit #f59a7031)

Just expand the first bottom sheet.

Tim Malseed
  • 6,003
  • 6
  • 48
  • 66

2 Answers2

41

Where does the problem lies? In FrameLayout. BottomSheet works perfectly when put inside CoordinatorLayout. Then BottomSheet can pass it's scrolling state through CoordinatorLayout to other views put as direct children of CoordinatorLayout.

Why RecyclerView was not able to pass scroll state to BottomSheet? It is not a direct child of CoordinatorLayout. But there exists a way to pass them: RecyclerView must be in put in view that implements NestedScrollingParent and NestedScrollingChild. The answer to that is: NestedScrollView

So your fragment_sheetX.xml layouts should look like:

<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.NestedScrollView
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#fff"
    android:orientation="vertical"
    android:fillViewport="true">

    <android.support.v7.widget.RecyclerView
        android:id="@+id/recyclerView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>

</android.support.v4.widget.NestedScrollView>

Notice also android:fillViewport="true" as otherwise, your RecyclerView will not take whole height.

However it still will not work. Why? RecyclerView must be told to pass vertical scrolling to parent. How? The answer is recyclerView.setNestedScrollingEnabled(false);, but that is better described here.

Btw: MultiSheetView is a great feature and a very interesting approach to mobile UX design.

azizbekian
  • 60,783
  • 13
  • 169
  • 249
R. Zagórski
  • 20,020
  • 5
  • 65
  • 90
  • I suspected the`FrameLayout` preventing scroll events from propagating to the `CoordinatorLayout`. I think I got close to this solution at some point, but had trouble with the viewport problem. Thanks so much. – Tim Malseed Jun 26 '17 at 01:50
  • 1
    if the hierarchy is: NestedScrollView -> ConstraintLayout -> RecylerView, the RecyclerView scrolling doesn´t behave correctly...I can scroll down but not up. When trying to scroll up, the Bottomsheet (in this case NestedScrollView) collapses...any Idea? – skm Jan 06 '19 at 10:01
  • 16
    This method causes the `RecyclerView` to have height equivalent to `wrap_content`, which is _terrible_ for performance as it causes `ViewHolder`s for all children to be inflated individually without reuse – Josh Jan 18 '19 at 20:17
  • Thank you so much, this answer solved my problem. – Fereshteh Naji Apr 17 '21 at 08:18
  • This will not recycle view inside recycle view.. – Rohit Dec 23 '21 at 10:36
  • @skm, have you found an answer, how to make RecylerView scrollable both ways in BottomSheet? I have the same problem in my project – d.u.a.l Nov 15 '22 at 15:20
0
android:nestedScrollingEnabled="false"

Setting this in recyclerview solved the problem

Tyler2P
  • 2,324
  • 26
  • 22
  • 31
Amit kumar
  • 149
  • 14