嵌套的RecyclerView滚动问题

时间:2018-04-04 13:14:41

标签: android scroll android-recyclerview nestedrecyclerview

在我的应用程序中,我有一个垂直父RecyclerView,其ViewHolders内的水平子项很少。但我有非常烦人的滚动问题 - 在我垂直滚动父RV之后我想滚动我的一个孩子RV但父母只是拦截所有的动作事件,直到我从屏幕上移开我的手指然后把它放回去。以下是这种烦人行为的例子。

https://i.imgur.com/dPtmAXD.gif

我尝试了这个问题的每个解决方案 - Nested RecyclerView. How to prevent parent RecyclerView from getting scrolled while child RecyclerView is scrolling?

对我来说没有任何作用。

看起来Google Play Market拥有相同的RV层次结构,但是滚动完全没问题。我尝试从其他主题实现一些解决方案,但没有任何工作按预期工作。

我不知道我应该发布什么代码,但这里是我的父RV的ViewHolder嵌套RV示例。

private class UserEventsViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
        private RecyclerView rvUserEvents;
        private HomeUserEventsRVAdapter rvAdapter;

        public UserEventsViewHolder(View v) {
            super(v);

            rvUserEvents = v.findViewById(R.id.rv_user_events);
            rvUserEvents.setLayoutManager(new LinearLayoutManager(itemView.getContext(), LinearLayoutManager.HORIZONTAL, false));
            rvUserEvents.setNestedScrollingEnabled(false);
            rvUserEvents.setRecycledViewPool(viewPool);
            rvAdapter = new HomeUserEventsRVAdapter(presenter);
            rvUserEvents.setAdapter(rvAdapter);

            v.findViewById(R.id.btn_all_user_events).setOnClickListener(this);
        }

        private void bind(UserItemViewModel userItem) {
            rvAdapter.updateAdapter(userItem);
        }

        @Override
        public void onClick(View v) {
            switch (v.getId()) {
                case R.id.btn_all_user_events:
                    presenter.openUserEventsList();
                    break;
            }
        }
    }

编辑:我的活动的XML代码

<android.support.design.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/cl_root"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@android:color/white">

<android.support.design.widget.AppBarLayout
    android:id="@+id/ab_layout"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
    android:fitsSystemWindows="true">

    <android.support.design.widget.CollapsingToolbarLayout
        android:id="@+id/collapsing_toolbar"
        android:layout_width="match_parent"
        android:layout_height="190dp"
        app:layout_scrollFlags="scroll|exitUntilCollapsed"
        android:fitsSystemWindows="true"
        app:contentScrim="@android:color/white"
        app:expandedTitleMarginStart="48dp"
        app:expandedTitleMarginEnd="64dp">

        <ImageView
            android:id="@+id/iv_pic"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:scaleType="centerCrop"
            android:src="@drawable/ic_home_screen_background"
            android:fitsSystemWindows="true"
            app:layout_collapseMode="parallax"
            app:layout_collapseParallaxMultiplier="0.5"/>

        <android.support.v7.widget.Toolbar
            android:id="@+id/toolbar"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            android:elevation="7dp"
            android:theme="@style/ToolbarTheme"
            app:layout_collapseMode="pin"/>
    </android.support.design.widget.CollapsingToolbarLayout>
</android.support.design.widget.AppBarLayout>

<android.support.v4.widget.SwipeRefreshLayout
    android:id="@+id/sr_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_marginTop="-6dp"
    app:layout_behavior="@string/appbar_scrolling_view_behavior">

    <android.support.v7.widget.RecyclerView
        android:id="@+id/rv_results"
        android:clipToPadding="false"
        android:scrollbars="vertical"
        android:scrollbarThumbVertical="@color/orange_juice_80"
        android:scrollbarSize="2dp"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@drawable/shape_rounded_top_grey"
        android:fitsSystemWindows="true" />
</android.support.v4.widget.SwipeRefreshLayout>

<android.support.design.widget.FloatingActionButton
    android:id="@+id/fab_add"
    android:layout_width="56dp"
    android:layout_height="56dp"
    android:layout_marginEnd="15dp"
    app:backgroundTint="@color/dark_background"
    app:layout_anchor="@id/rv_results"
    app:layout_anchorGravity="top|right|end"
    app:layout_scrollFlags="scroll|exitUntilCollapsed"
    app:srcCompat="@drawable/ic_vector_plus_white" />

4 个答案:

答案 0 :(得分:0)

您在此行中禁用了RecyclerView的嵌套滚动

rvUserEvents.setNestedScrollingEnabled(false);

您需要用以下内容替换此行才能正常滚动

ViewCompat.setNestedScrollingEnabled(rvUserEvents,true);

答案 1 :(得分:0)

我没有注意到这种特殊行为,但是当包含水平滚动视图的垂直RecyclerView被抛出然后停止时,RecyclerView会保留在触摸流上,因此只有RecyclerView可以滚动。水平视图无法滚动,直到指针被抬起然后重新应用到屏幕上。

要解决此问题,请应用以下代码:

mRecyclerView.addOnItemTouchListener(
        new RecyclerView.SimpleOnItemTouchListener() {
            @Override
            public boolean onInterceptTouchEvent(RecyclerView rv, MotionEvent e) {
                if (e.getAction() == MotionEvent.ACTION_DOWN
                        && rv.getScrollState() == RecyclerView.SCROLL_STATE_SETTLING) {
                    rv.stopScroll();
                }
                return false;
            }
        }
);

此代码将从RecyclerView释放触摸流,这将允许水平可滚动视图在下一个移动动作中进行拍摄。请参阅RecyclerView.SimpleOnItemTouchListener

答案 2 :(得分:0)

<androidx.recyclerview.widget.RecyclerView
     android:id="@+id/recyclerView"
     android:layout_width="match_parent"
     android:descendantFocusability="blocksDescendants"
     android:layout_height="wrap_content"
     android:scrollbars="none" />
  

在嵌套的recyclerview中使用android:descendantFocusability =“ blocksDescendants”属性

答案 3 :(得分:-2)

 recyclerView.setNestedScrollingEnabled(false);