[英]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 .我需要类似于此实现的行为但 NestedScrollView 将是父级, RecyclerView 将是 NestedScrollView 的子级。
Eg: https://medium.com/widgetlabs-engineering/scrollable-nestedscrollviews-inside-recyclerview-ca65050d828a例如: 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.我不确定它是否可以实现。尝试在 child(RV) 滚动时禁用 parent(NSV),但是在 child 上滚动会滚动整个视图,包括 parent。
I'v implemented Marc Knaup solution and all works correct event if NestedScrollView
would be the parent and the result was shown below我已经实现了Marc Knaup解决方案,并且如果
NestedScrollView
是父项并且结果显示如下,则所有事件都可以正常工作
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 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
<?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>
post entire thing what you have tried so far.发布您迄今为止尝试过的全部内容。
your xml should be ,你的 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>
set scrolling behaviour inside onCreateView() / onCreate() method.在 onCreateView() / onCreate() 方法中设置滚动行为。 requires Api 21+ .
需要 Api 21+ 。
RecyclerView v = (RecyclerView) findViewById(...);
v.setNestedScrollingEnabled(false);
or
android:nestedScrollingEnabled="false" // inside recycler view in xml file
@Rockin use overscrollmode bro:) @Rockin 使用 overscrollmode 兄弟:)
<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" />
This is demo for what you want look, In MainActivity.xml file :这是您想要的演示,在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>
In your MainActivity.java class onCreate
method:在您的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);
I hope It'll help you...!我希望它会帮助你...!
In general simple trick works for me.一般来说,简单的技巧对我有用。 When attaching OnTouchListener to child View, in onTouch() just disable touch interrupts.
将 OnTouchListener 附加到子视图时,在 onTouch() 中仅禁用触摸中断。 Something like this:
像这样的东西:
RecyclerView rv = findViewById(...);
rv.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
...
v.getParent().requestDisallowInterceptTouchEvent(true);
Have you try subclass the RV and override onInterceptTouchEvent?您是否尝试将 RV 子类化并覆盖 onInterceptTouchEvent?
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
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.