RecyclerView (horizontal) nested in BottomSheet preventing vertical scrolling
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.
Related videos on Youtube
Tim Malseed
Software Engineer at IttyBittyApps. Creator of Shuttle Music Player.
Updated on June 04, 2022Comments
-
Tim Malseed almost 2 years
I have a
RecyclerView
using aLinearLayoutManager
withHORIZONTAL
orientation, nested inside aFrameLayout
using theBottomSheet
Behavior
.When attempting to drag vertically across the
RecyclerView
, theBottomSheet
doesn't respond to the drag event. Presumably this is because vertical scrolling is disabled for aLayoutManager
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, theBottomSheet
will respond. As soon as any horizontal movement is involved however, theBottomSheet
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 aRecyclerView
with a horizontally orientedLayoutManager
, theBottomSheet
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 theBottomSheet 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 almost 7 yearsI suspected the
FrameLayout
preventing scroll events from propagating to theCoordinatorLayout
. I think I got close to this solution at some point, but had trouble with the viewport problem. Thanks so much. -
skm over 5 yearsif 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?
-
Josh over 5 yearsThis method causes the
RecyclerView
to have height equivalent towrap_content
, which is terrible for performance as it causesViewHolder
s for all children to be inflated individually without reuse -
Fereshteh Naji about 3 yearsThank you so much, this answer solved my problem.
-
Rohit over 2 yearsThis will not recycle view inside recycle view..