Bildlauf des übergeordneten Elements stoppen (NestedScrollview) Beim Scrollen des untergeordneten Elements (RecyclerView)


8

Ich benötige ein ähnliches Verhalten wie diese Implementierung. NestedScrollView wäre jedoch das übergeordnete Element und RecyclerView das untergeordnete Element von NestedScrollView.

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

Ich bin nicht sicher, ob dies erreicht werden kann. Versucht, das Deaktivieren des übergeordneten Elements (NSV) zu deaktivieren, während das untergeordnete Element (RV) einen Bildlauf durchführt. Beim Scrollen des untergeordneten Elements wird jedoch die gesamte Ansicht einschließlich des übergeordneten Elements gescrollt.


Antworten:


2

Ich habe die Marc Knaup- Lösung implementiert und alles funktioniert korrekt, wenn NestedScrollViewdas übergeordnete Element wäre und das Ergebnis unten gezeigt wird

Geben Sie hier die Bildbeschreibung ein

Übrigens habe ich gesagt, was ich getan habe

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>

0

@ Rockin benutze Overscrollmode Bruder :)

 <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" />

Das in diesem Medium / scrollgetlabs-engineering/… erwähnte Bildlaufverhalten kann im Overscroll-Modus nicht erreicht werden.
Rockin

@Rockin du musst android geben: layout_height = "match_parent" und es funktioniert trotzig ich benutze dies in meinem Code.
Parth Pitroda

0

poste die ganze Sache, was du bisher versucht hast.

Ihre XML sollte sein,

<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>

Legen Sie das Bildlaufverhalten in der Methode onCreateView () / onCreate () fest. erfordert Api 21+.

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

Das in diesem Medium / scrollgetlabs-engineering/… erwähnte Bildlaufverhalten kann im Overscroll-Modus nicht erreicht werden.
Rockin

Dies ist keine Lösung, da android: nestedScrollingEnabled = "false" recycleview einfrieren.
Mr.AF

0

Dies ist eine Demo für das, was Sie in der Datei MainActivity.xml sehen möchten :

<?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>

In Ihrer MainActivity.java- Klassenmethode 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);

Geben Sie hier die Bildbeschreibung ein

Ich hoffe es wird dir helfen ...!


Haben Sie Ihre Antworten gefunden oder brauchen Sie Hilfe?
Viral Patel

Ist es hilfreich für dich?
Viral Patel

-1

Haben Sie versucht, das Wohnmobil zu unterklassifizieren und onInterceptTouchEvent zu überschreiben?

override fun onInterceptTouchEvent(event: MotionEvent?): Boolean {

    when (event!!.action and MotionEvent.ACTION_MASK) {


        MotionEvent.ACTION_DOWN -> {

            // WE INTERACT WITH THIS RV. PREVENT PARENT TO INTERCEPT 
            parent.requestDisallowInterceptTouchEvent(true) 

        }


        MotionEvent.ACTION_MOVE, MotionEvent.ACTION_CANCEL, MotionEvent.ACTION_UP -> {

            // THIS SEEMS LIKE IT WILL HAVE "DEFAULT" BEHAVIOUR BUT SINCE WE CURRENTLY DRAGGING THE RV THEN IT WONT SCROLL THE PARENT  
            parent.requestDisallowInterceptTouchEvent(false)

        }

    }

    return false
}
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.