Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Stop scroll of parent (NestedScrollview) When scrolling Child(RecyclerView)

I need behavior similar to this implementation But NestedScrollView would be the parent and RecyclerView would be the child of would NestedScrollView .

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

I am not sure whether it can be achieved.Tried disabling the of parent(NSV) while child(RV)is scrolling But scroll on child scrolls the entire view including parent.

like image 883
Rockin Avatar asked Nov 30 '19 17:11

Rockin


People also ask

How do I stop NestedScrollView scrolling?

setnestedscrollingenabled set it to false.

How do I stop refreshing RecyclerView data scroll to top position android?

Just set your LayoutManager and adapter for the first time. Make a setDataList method in your adapter class. And set your updated list to adapter list. And then every time of calling API set that list to setDataList and call adapter.

What is the difference between NestedScrollView and ScrollView?

NestedScrollView is just like ScrollView , but it supports acting as both a nested scrolling parent and child on both new and old versions of Android. Nested scrolling is enabled by default.

How do I make my recycler view Unscrollable?

If you just disable only scroll functionality of RecyclerView then you can use setLayoutFrozen(true); method of RecyclerView .


1 Answers

I'v implemented Marc Knaup solution and all works correct event if NestedScrollView would be the parent and the result was shown below

enter image description here

btw, i put what i'v done

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>
like image 166
A Farmanbar Avatar answered Sep 16 '22 14:09

A Farmanbar