嵌套在BottomSheet中的RecyclerView(水平)可防止垂直滚动 [英] RecyclerView (horizontal) nested in BottomSheet preventing vertical scrolling

查看:577
本文介绍了嵌套在BottomSheet中的RecyclerView(水平)可防止垂直滚动的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个RecyclerView,它使用LinearLayoutManager且方向为HORIZONTAL,并使用BottomSheet Behavior嵌套在FrameLayout内.

当尝试在RecyclerView上垂直拖动时,BottomSheet不会响应拖动事件.大概是因为LayoutManager水平方向禁用了垂直滚动.

我尝试覆盖LinearLayoutManager.canScrollVertically()并返回true.这种 的工作原理..如果您以非常谨慎的方式垂直拖动,则BottomSheet将会响应.但是,一旦涉及到任何水平移动,BottomSheet就会停止响应垂直拖动事件.

我不确定覆盖canScrollVertically()是否是正确的方法-从UX的角度来看肯定不正确.

我还注意到,如果我使用ViewPager而不是水平放置LayoutManagerRecyclerView,则BottomSheet会根据需要响应垂直滑动事件.

还有LayoutManagerRecyclerViewBottomSheet 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆