Android的布局:与滚动行为一Viewpager内垂直Recyclerview水平内Recyclerview [英] Android Layout: Horizontal Recyclerview inside a Vertical Recyclerview inside a Viewpager with Scroll Behaviors

查看:1471
本文介绍了Android的布局:与滚动行为一Viewpager内垂直Recyclerview水平内Recyclerview的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是我试图建立与上述映射出的所有元素的应用程序:

This is the app I'm trying to build with all the elements mapped out below:

一切正常,但是,我想内水平面recyclerview没有捕捉到任何垂直卷轴。所有垂直滚动必须朝着外垂直recyclerview,而不是水平的,从而使垂直滚动将允许工具栏根据它scrollFlag到的视图退出出

Everything works, however, I want the inner horizontal recyclerview not to capture any of the vertical scrolls. All vertical scrolls must go towards the outer vertical recyclerview, not the horizontal one, so that the vertical scroll would allow for the toolbar to exit out of view according to it's scrollFlag.

当我把我的手指上recyclerview的草莓厂部分,滚动,滚动它从工具栏:

When I put my finger on the "StrawBerry Plant" part of the recyclerview and scroll up, it scroll out the toolbar:

如果我把我的手指上的水平滚动视图和滚动,它根本不滚动出工具栏。

If I put my finger on the horizontal scrollview and scroll up, it does not scroll out the toolbar at all.

下面是我的XML布局code为止。

The following is my xml layout code so far.

活动 XML布局:

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:id="@+id/fragment_container"
    android:clipChildren="false">

    <android.support.design.widget.CoordinatorLayout
        android:orientation="vertical"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:id="@+id/container"
        >

    <android.support.design.widget.AppBarLayout
        android:id="@+id/appBarLayout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <android.support.v7.widget.Toolbar
            android:id="@+id/toolbar"
            android:minHeight="?attr/actionBarSize"
            android:background="?attr/colorPrimary"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            app:layout_scrollFlags="scroll|enterAlways">

        </android.support.v7.widget.Toolbar>

        <android.support.design.widget.TabLayout
            android:id="@+id/sliding_tabs"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:background="?attr/colorPrimary"
            style="@style/CustomTabLayout"
            />

    </android.support.design.widget.AppBarLayout>
    <android.support.v4.view.ViewPager
        android:id="@+id/viewPager"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:layout_behavior="@string/appbar_scrolling_view_behavior"
        />

    </android.support.design.widget.CoordinatorLayout>

</FrameLayout>

水果片段 XML布局(这是code的片段 - 片段标记在上面的图片):

The "Fruits" fragment xml layout (which is the code for the fragment - the fragment is labeled in the above picture):

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <ProgressBar
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/progressBar"
        android:visibility="gone"
        android:layout_centerInParent="true"
        android:indeterminate="true"/>

<!--    <android.support.v7.widget.RecyclerView-->
    <com.example.simon.customshapes.VerticallyScrollRecyclerView
        android:id="@+id/main_recyclerview"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        />

</RelativeLayout>

我使用了被称为VerticallyScrollRecyclerView一个自定义的类如下的处理的ViewGroup触摸事件谷歌的例子。其目的是拦截和消耗所有垂直滚动事件,以便将输入/输出工具栏滚动:<一href=\"http://developer.android.com/training/gestures/viewgroup.html\">http://developer.android.com/training/gestures/viewgroup.html

在code对于 VerticallyScrollRecyclerView 是如下:

The code for VerticallyScrollRecyclerView is below:

public class VerticallyScrollRecyclerView extends RecyclerView {

    public VerticallyScrollRecyclerView(Context context) {
        super(context);
    }

    public VerticallyScrollRecyclerView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public VerticallyScrollRecyclerView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }

    ViewConfiguration vc = ViewConfiguration.get(this.getContext());
    private int mTouchSlop = vc.getScaledTouchSlop();
    private boolean mIsScrolling;
    private float startY;

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        final int action = MotionEventCompat.getActionMasked(ev);
        // Always handle the case of the touch gesture being complete.
        if (action == MotionEvent.ACTION_CANCEL || action == MotionEvent.ACTION_UP) {
            // Release the scroll.
            mIsScrolling = false;
            startY = ev.getY();
            return super.onInterceptTouchEvent(ev); // Do not intercept touch event, let the child handle it
        }
        switch (action) {
            case MotionEvent.ACTION_MOVE: {
                Log.e("VRecView", "its moving");
                if (mIsScrolling) {
                    // We're currently scrolling, so yes, intercept the
                    // touch event!
                    return true;
                }
                // If the user has dragged her finger horizontally more than
                // the touch slop, start the scroll
                // left as an exercise for the reader
                final float yDiff = calculateDistanceY(ev.getY());
                Log.e("yDiff ", ""+yDiff);
                // Touch slop should be calculated using ViewConfiguration
                // constants.
                if (Math.abs(yDiff) > 5) {
                    // Start scrolling!
                    Log.e("Scroll", "we are scrolling vertically");
                    mIsScrolling = true;
                    return true;
                }
                break;
            }
        }
        return super.onInterceptTouchEvent(ev);
    }


    private float calculateDistanceY(float endY) {
        return startY - endY;
    }

}

收藏布局这是垂直recyclerview内recyclerview:

The "Favourite" layout which is the recyclerview within the vertical recyclerview:

<?xml version="1.0" encoding="utf-8"?>

<RelativeLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:background="@color/white"
    xmlns:app="http://schemas.android.com/apk/res-auto">

    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Favourite"
        android:layout_marginTop="8dp"
        android:layout_marginBottom="8dp"
        android:layout_marginLeft="16dp"
        android:id="@+id/header_fav"/>

    <android.support.v7.widget.RecyclerView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        android:layout_below="@+id/header_fav"
        android:id="@+id/recyclerview_fav">
    </android.support.v7.widget.RecyclerView>

</RelativeLayout>

这已经现在缠着我了一会儿,我没有设法拿出一个解决方案。有谁知道如何解决这个问题?

This has been bugging me for a while now and I have not managed to come up with a solution. Does anyone know how to solve this problem?

5分Griffindor为正确答案,当然,口碑那么点上。

5 points to Griffindor for the correct answer and of course, reputation points on SO.

推荐答案

测试的解决方案:

您只需要调用 mInnerRecycler.setNestedScrollingEnabled(假); 在你的内心 RecyclerView 取值

All you need is to call mInnerRecycler.setNestedScrollingEnabled(false); on your inner RecyclerViews



说明

RecyclerView 对通过实施 NestedScrollingChild <在 API 21 介绍嵌套的滚动支持/ code>接口。这是一个有价值的功能,当你有在另一个在同一个方向上滚动滚动视图,并要滚动内查看集中时才会出现。

RecyclerView has support for nested scrolling introduced in API 21 through implementing the NestedScrollingChild interface. This is a valuable feature when you have a scrolling view inside another one that scrolls in the same direction and you want to scroll the inner View only when focused.

在任何情况下, RecyclerView 默认调用 RecyclerView.setNestedScrollingEnabled(真); 本身时初始化。现在,回到这个问题,因为这两个你的 RecyclerView 取值都在同一 ViewPager 具有 AppBarBehavior CoordinateLayout 必须决定哪些滚动回应,当你从你的内心 RecyclerView ;当启用了你内心的 RecyclerView 的嵌套滚动,它就会滚动焦点和 CoordinateLayout 会选择响应其滚动在外部 RecyclerView 的滚动。事情是这样的,因为你的内心 RecyclerView ■不要垂直滚动,就没有垂直滚动的变化(从 CoordinateLayout 的观点),如果没有变化,则 AppBarLayout 也不改变。

In any case, RecyclerView by default calls RecyclerView.setNestedScrollingEnabled(true); on itself when initializing. Now, back to the problem, since both of your RecyclerViews are within the same ViewPager that has the AppBarBehavior, the CoordinateLayout has to decide which scroll to respond to when you scroll from your inner RecyclerView; when your inner RecyclerView's nested scrolling is enabled, it gets the scrolling focus and the CoordinateLayout will choose to respond to its scrolling over the outer RecyclerView's scrolling. The thing is that, since your inner RecyclerViews don't scroll vertically, there is no vertical scroll change (from the CoordinateLayout's point of view), and if there is no change, the AppBarLayout doesn't change either.

在你的情况,因为你内心的 RecyclerView ,则在不同的方向滚动,你可以禁用它,从而导致 CoordinateLayout 无视它的滚​​动和外 RecyclerView 的滚动回应。

In your case, because your inner RecyclerViews are scrolling in a different direction, you can disable it, thus causing the CoordinateLayout to disregard its scrolling and respond to the outer RecyclerView's scrolling.


的通知

XML属性的android:nestedScrollingEnabled =布尔不能用于与 RecyclerView ,以及使用尝试使用的android:nestedScrollingEnabled =FALSE将导致显示java.lang.NullPointerException 那么,至少现在,你将不得不做,在code。

The xml attribute android:nestedScrollingEnabled="boolean" is not intended for use with the RecyclerView, and an attempt to use android:nestedScrollingEnabled="false" will result in a java.lang.NullPointerException so, at least for now, you will have to do it in code.

这篇关于Android的布局:与滚动行为一Viewpager内垂直Recyclerview水平内Recyclerview的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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