嵌套在BottomSheet中的RecyclerView(水平)可防止垂直滚动 [英] RecyclerView (horizontal) nested in BottomSheet preventing vertical scrolling
问题描述
我有一个RecyclerView
,它使用LinearLayoutManager
且方向为HORIZONTAL
,并使用BottomSheet
Behavior
嵌套在FrameLayout
内.
当尝试在RecyclerView
上垂直拖动时,BottomSheet
不会响应拖动事件.大概是因为LayoutManager
水平方向禁用了垂直滚动.
我尝试覆盖LinearLayoutManager.canScrollVertically()
并返回true.这种 的工作原理..如果您以非常谨慎的方式垂直拖动,则BottomSheet
将会响应.但是,一旦涉及到任何水平移动,BottomSheet
就会停止响应垂直拖动事件.
我不确定覆盖canScrollVertically()
是否是正确的方法-从UX的角度来看肯定不正确.
我还注意到,如果我使用ViewPager
而不是水平放置LayoutManager
的RecyclerView
,则BottomSheet
会根据需要响应垂直滑动事件.
还有LayoutManager
,RecyclerView
,BottomSheet Behavior
的其他方法,还是可以将垂直滚动事件传播到BottomSheet Behavior
的其他方法?
这里有一个问题的例子:
https://github.com/timusus/bottomsheet-test (问题可以通过提交#f59a7031复制)
只需展开第一底页.
问题出在哪里?在FrameLayout
中.将BottomSheet
放在CoordinatorLayout
中时,效果很好.然后BottomSheet
可以将其滚动状态通过CoordinatorLayout
传递到作为CoordinatorLayout
的直接子代放置的其他视图.
为什么RecyclerView
无法将滚动状态传递给BottomSheet
?它不是CoordinatorLayout
的直接子代.但是存在一种传递它们的方法:必须在实现RecyclerView ="noreferrer"> NestedScrollingParent
和 NestedScrollView
>
因此,您的fragment_sheetX.xml
布局应如下所示:
<?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>
也请注意android:fillViewport="true"
,否则您的RecyclerView
不会占据整个高度.
但是它仍然无法正常工作.为什么?必须告诉RecyclerView
将垂直滚动传递给父级.如何?答案是recyclerView.setNestedScrollingEnabled(false);
,但此处对此进行了更好的描述.
顺便说一句:MultiSheetView
是移动UX设计的重要功能和非常有趣的方法.
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.
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.
这篇关于嵌套在BottomSheet中的RecyclerView(水平)可防止垂直滚动的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!