web-dev-qa-db-ja.com

親のスクロールを停止(NestedScrollview)子をスクロールするとき(RecyclerView)

この実装と同様の動作が必要ですが、NestedScrollViewが親になり、RecyclerViewがNestedScrollViewの子になります。

例: https://medium.com/widgetlabs-engineering/scrollable-nestedscrollviews-inside-recyclerview-ca65050d828a

子(RV)がスクロールしているときに親(NSV)の無効化を試みましたが、子でスクロールすると、親を含むビュー全体がスクロールされます。

8
Rockin

私は実装しました Marc Knaup ソリューションで、NestedScrollViewが親であり、結果が以下に示されている場合、すべてが正しいイベントを機能します

enter image description here

ところで、私は私がやったことを入れます

CustomRecycleView

package com.example.nested_scroll_test;

import Android.content.Context;
import Android.util.AttributeSet;
import Android.view.MotionEvent;
import Android.view.View;

import androidx.core.view.NestedScrollingParent;
import androidx.recyclerview.widget.RecyclerView;

public class CustomRecycleView extends RecyclerView implements NestedScrollingParent {
    private View nestedScrollTarget = null;
    private boolean nestedScrollTargetIsBeingDragged = false;
    private boolean nestedScrollTargetWasUnableToScroll = false;
    private boolean skipsTouchInterception = false;


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

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

    public CustomRecycleView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }


    @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
        boolean temporarilySkipsInterception = nestedScrollTarget != null;
        if (temporarilySkipsInterception) {
            // If a descendent view is scrolling we set a flag to temporarily skip our onInterceptTouchEvent implementation
            skipsTouchInterception = true;
        }

        // First dispatch, potentially skipping our onInterceptTouchEvent
        boolean handled = super.dispatchTouchEvent(ev);

        if (temporarilySkipsInterception) {
            skipsTouchInterception = false;

            // If the first dispatch yielded no result or we noticed that the descendent view is unable to scroll in the
            // direction the user is scrolling, we dispatch once more but without skipping our onInterceptTouchEvent.
            // Note that RecyclerView automatically cancels active touches of all its descendents once it starts scrolling
            // so we don't have to do that.
            if (!handled || nestedScrollTargetWasUnableToScroll) {
                handled = super.dispatchTouchEvent(ev);
            }
        }

        return handled;
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent e) {
        return !skipsTouchInterception && super.onInterceptTouchEvent(e);
    }

    @Override
    public void onNestedScroll(View target, int dxConsumed, int dyConsumed, int dxUnconsumed, int dyUnconsumed) {
        if (dyConsumed != 0) {
            // The descendent was actually scrolled, so we won't bother it any longer.
            // It will receive all future events until it finished scrolling.
            nestedScrollTargetIsBeingDragged = true;
            nestedScrollTargetWasUnableToScroll = false;
        } else if (dyConsumed == 0 && dyUnconsumed != 0) {
            // The descendent tried scrolling in response to touch movements but was not able to do so.
            // We remember that in order to allow RecyclerView to take over scrolling.
            nestedScrollTargetWasUnableToScroll = true;
            if (target.getParent() != null)
                target.getParent().requestDisallowInterceptTouchEvent(false);
        }
    }

    @Override
    public void onNestedScrollAccepted(View child, View target, int axes) {
        if (axes != 0 && View.SCROLL_AXIS_VERTICAL != 0) {
            // A descendent started scrolling, so we'll observe it.
            nestedScrollTarget = target;
            nestedScrollTargetIsBeingDragged = false;
            nestedScrollTargetWasUnableToScroll = false;
        }

        super.onNestedScrollAccepted(child, target, axes);
    }

    @Override
    public boolean onStartNestedScroll(View child, View target, int nestedScrollAxes) {
        return nestedScrollAxes != 0 && View.SCROLL_AXIS_VERTICAL != 0;
    }

    @Override
    public void onStopNestedScroll(View child) {
        nestedScrollTarget = null;
        nestedScrollTargetIsBeingDragged = false;
        nestedScrollTargetWasUnableToScroll = false;
    }
}

content_main.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
    xmlns:app="http://schemas.Android.com/apk/res-auto"
    xmlns:tools="http://schemas.Android.com/tools"
    Android:layout_width="match_parent"
    Android:layout_height="match_parent"
    app:layout_behavior="@string/appbar_scrolling_view_behavior"
    tools:context=".MainActivity"
    tools:showIn="@layout/activity_main">


    <androidx.core.widget.NestedScrollView
        Android:layout_width="match_parent"
        Android:layout_height="wrap_content"
        Android:background="@color/colorAccent"
        Android:orientation="vertical">

        <LinearLayout
            Android:layout_width="match_parent"
            Android:layout_height="match_parent"
            Android:orientation="vertical">

            <LinearLayout
                Android:layout_width="match_parent"
                Android:layout_height="150dp"
                Android:background="#FFFFFF"
                Android:orientation="vertical">
                <TextView
                    Android:layout_width="match_parent"
                    Android:layout_height="match_parent"
                    Android:textAlignment="center"
                    Android:text="Top Section"/>
            </LinearLayout>

            <com.example.nested_scroll_test.CustomRecycleView
                Android:id="@+id/rw"
                Android:layout_width="match_parent"
                Android:layout_height="300dp"
                Android:background="@color/colorPrimary"
                Android:nestedScrollingEnabled="true"
                Android:orientation="vertical">

            </com.example.nested_scroll_test.CustomRecycleView>

            <LinearLayout
                Android:layout_width="match_parent"
                Android:layout_height="150dp"
                Android:background="#FFFFFF"
                Android:orientation="vertical" >
                <TextView
                    Android:layout_width="match_parent"
                    Android:layout_height="match_parent"
                    Android:textAlignment="center"
                    Android:text="Bottom Section"/>
            </LinearLayout>
        </LinearLayout>
    </androidx.core.widget.NestedScrollView>


</androidx.coordinatorlayout.widget.CoordinatorLayout>

RecycleViewItem.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.core.widget.NestedScrollView xmlns:Android="http://schemas.Android.com/apk/res/Android"
    Android:id="@+id/nsw"
    Android:layout_width="match_parent"
    Android:layout_height="50dp"
    Android:orientation="vertical">

    <TextView
        Android:id="@+id/textview"
        Android:layout_width="match_parent"
        Android:layout_height="wrap_content"
        Android:layout_margin="2dp"
        Android:background="#CCCC"
        Android:gravity="center"
        Android:nestedScrollingEnabled="false"
        Android:orientation="vertical"
        Android:padding="2dp"
        Android:textColor="#FFFFFF" />
</androidx.core.widget.NestedScrollView>
2
Mr.AF

これはあなたが見たいもののデモです、MainActivity.xmlファイルで:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
    xmlns:tools="http://schemas.Android.com/tools"
    Android:layout_width="match_parent"
    Android:layout_height="match_parent"
    Android:orientation="vertical"
    tools:context="MainActivity">

    <Android.support.v4.widget.NestedScrollView
        Android:layout_width="match_parent"
        Android:layout_height="wrap_content"
        Android:scrollbars="none">
        <LinearLayout
            Android:layout_width="match_parent"
            Android:layout_height="wrap_content"
            Android:focusableInTouchMode="true"
            Android:orientation="vertical">
            <ImageView
                Android:id="@+id/top_seller"
                Android:layout_width="match_parent"
                Android:layout_height="200sp"
                Android:background="@color/colorAccent"
                Android:contentDescription="@string/app_name"
                Android:adjustViewBounds="true"
                Android:src="@drawable/background"
                Android:scaleType="fitXY"/>
            <ImageView
                Android:id="@+id/top_seller1"
                Android:layout_width="match_parent"
                Android:layout_height="200sp"
                Android:background="@color/colorAccent"
                Android:contentDescription="@string/app_name"
                Android:adjustViewBounds="true"
                Android:src="@drawable/background"
                Android:scaleType="fitXY"/>
            <Android.support.v7.widget.RecyclerView
                Android:id="@+id/product_list"
                Android:layout_width="match_parent"
                Android:layout_height="match_parent"
                Android:orientation="vertical"
                Android:scrollbars="none" />
            <ImageView
                Android:id="@+id/top_seller2"
                Android:layout_width="match_parent"
                Android:layout_height="200sp"
                Android:background="@color/colorAccent"
                Android:contentDescription="@string/app_name"
                Android:adjustViewBounds="true"
                Android:src="@drawable/background"
                Android:scaleType="fitXY"/>
            <ImageView
                Android:id="@+id/top_seller3"
                Android:layout_width="match_parent"
                Android:layout_height="200sp"
                Android:background="@color/colorAccent"
                Android:contentDescription="@string/app_name"
                Android:adjustViewBounds="true"
                Android:src="@drawable/background"
                Android:scaleType="fitXY"/>
        </LinearLayout>
    </Android.support.v4.widget.NestedScrollView>
</LinearLayout>

MainActivity.JavaクラスonCreateメソッドで:

   RecyclerView bestRecyclerView = findViewById(R.id.product_list);
   GridLayoutManager mGrid = new GridLayoutManager(this, 2);
   bestRecyclerView.setLayoutManager(mGrid);
   bestRecyclerView.setHasFixedSize(true);
   bestRecyclerView.setNestedScrollingEnabled(false);
   // Create ProductAdapter for  RecyclerView data
   ProductAdapter mAdapter = new ProductAdapter(MainActivity4.this,getProductTestData());
   bestRecyclerView.setAdapter(mAdapter);

enter image description here

お役に立てれば幸いです...!

0
Viral Patel

これまでに試したことをすべて投稿してください。

あなたのxmlは

<Android.support.v4.widget.NestedScrollView
            Android:id="@+id/nestedScrollView"
            Android:layout_width="match_parent"
            Android:layout_height="match_parent"
            Android:overScrollMode="never">


            <LinearLayout
                Android:layout_width="match_parent"
                Android:layout_height="wrap_content"
                Android:orientation="vertical">

              <View > <!-- upper content -->

              <!-- set recycler view with with wrap_content -->
              <Android.support.v7.widget.RecyclerView
                    Android:id="@+id/recyclerView"
                    Android:layout_width="match_parent"
                    Android:layout_height="wrap_content" />

            </LinearLayout>
      </Android.support.v4.widget.NestedScrollView>

onCreateView()/ onCreate()メソッド内でスクロール動作を設定します。 API 21+が必要です。

    RecyclerView v = (RecyclerView) findViewById(...);
    v.setNestedScrollingEnabled(false);
                   or 
    Android:nestedScrollingEnabled="false"  // inside recycler view in xml file
0
Radhey

@Rockinはoverscrollmode broを使用します:)

 <androidx.core.widget.NestedScrollView
    Android:layout_width="match_parent"
    Android:fillViewport="true"
    Android:overScrollMode="always"
    Android:layout_height="match_parent">

    <androidx.constraintlayout.widget.ConstraintLayout
        Android:layout_width="match_parent"
        Android:layout_height="match_parent"
        Android:background="@color/color_white"
        Android:orientation="vertical">


       <androidx.recyclerview.widget.RecyclerView                
           Android:id="@+id/activity_insight_recyclerview_list"
            Android:layout_width="match_parent"
            Android:layout_height="match_parent"
            Android:layout_marginTop="@dimen/_20sdp"
          app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
            tools:listitem="@layout/raw_insight" />
0
Parth Pitroda