垂直滚动视图触摸中断中的嵌套水平回收视图



我想实现一个包含垂直ScrollView的活动,该具有多个水平RecyceViews作为子级!

但有时我会遇到来自内部RecycleViews的奇怪触摸中断,当我尝试在垂直方向滚动并且我的触摸起点在项目(RecycleView(内部时,ScrollView滚动无法正常工作,并且无法在 Y 方向滚动!

我尝试实现自己的ScrollViewRecycleView来处理触摸操作,但问题仍然存在!

您可以在此视频中观看真实发生的事情: 我的应用程序问题视频

我的滚动视图:

public class MyScrollView extends ScrollView {
private GestureDetector mGestureDetector;
public MyScrollView(Context context, AttributeSet attrs) {
super(context, attrs);
mGestureDetector = new GestureDetector(context, new YScrollDetector());
setFadingEdgeLength(0);
}
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
return super.onInterceptTouchEvent(ev) && mGestureDetector.onTouchEvent(ev);
}
@Override
public boolean canScrollVertically(int direction) {
return true;
}

@Override
public boolean canScrollHorizontally(int direction) {
return false;
}
// Return false if we're scrolling in the x direction
class YScrollDetector extends GestureDetector.SimpleOnGestureListener {
@Override
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
boolean result=Math.abs(distanceY) > Math.abs(distanceX);
Log.d("ADAPTER MYSCR G = ",result+"");
return result;
}
}
}

我的回收视图:

public class MyRecycleView extends RecyclerView {
private GestureDetector mGestureDetector;
public MyRecycleView(Context context) {
super(context);
mGestureDetector = new GestureDetector(context, new MyRecycleView.XScrollDetector());
}
public MyRecycleView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
mGestureDetector = new GestureDetector(context, new MyRecycleView.XScrollDetector());
}
public MyRecycleView(Context context, @Nullable AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
mGestureDetector = new GestureDetector(context, new MyRecycleView.XScrollDetector());
}

@Override
public boolean onInterceptTouchEvent(MotionEvent e) {
boolean result=super.onInterceptTouchEvent(e) && mGestureDetector.onTouchEvent(e);
if(!result) {
Log.d("ADAPTER MYREC G = ",result+"");
View parent=((View) getParent());
while (parent!=null){
if(parent.getClass().getName().equals("class com.android.internal.policy.DecorView"))
break;
if(parent instanceof MyScrollView) {
Log.d("MY SCROLL VIEW","FOUND AS PARENT!");
((MyScrollView) parent).requestDisallowInterceptTouchEvent(false);
break;
}
parent= (View) parent.getParent();
}
this.stopScroll();
}
return result;
}
@Override
public boolean canScrollHorizontally(int direction) {
return true;
}

@Override
public boolean canScrollVertically(int direction) {
return false;
}
// Return false if we're scrolling in the y direction
class XScrollDetector extends GestureDetector.SimpleOnGestureListener {
@Override
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
boolean result=Math.abs(distanceY) < Math.abs(distanceX);
return result;
}
}
}

这是我的回收视图项目适配器xml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/lib/io.github.makbn.graphics"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_margin="2dp"
android:background="@android:color/transparent"
android:gravity="center"
android:orientation="vertical">
<android.support.v7.widget.CardView
android:id="@+id/graphics_card_container"
android:layout_width="115dp"
android:layout_height="180dp"
android:layout_marginBottom="3dp"
android:layout_marginLeft="4dp"
android:layout_marginRight="4dp"
android:layout_marginTop="1dp"
android:foreground="?android:attr/selectableItemBackground"
app:cardBackgroundColor="#fff"
android:clickable="true"
android:focusableInTouchMode="false"
android:filterTouchesWhenObscured="true"
android:focusable="false"
app:cardElevation="2dp"
app:cardPreventCornerOverlap="true">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="vertical">
<RelativeLayout
android:id="@+id/layout_foodview_container"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<ImageView
android:id="@+id/graphics_img_icon"
android:layout_width="match_parent"
android:layout_height="80dp"
android:layout_gravity="center"
android:background="#00000000"
android:scaleType="centerCrop" />
<RatingBar
style="@style/MyRatingBar_Style"
android:id="@+id/rating"
android:layout_width="match_parent"
android:layout_height="20dp"
android:layout_alignBottom="@+id/graphics_img_icon"
android:layout_centerInParent="true"
android:layout_gravity="center_horizontal"
android:isIndicator="true"
android:background="@color/white_overlay"
android:numStars="5" />
</RelativeLayout>
<TextView
android:id="@+id/txt_name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/img_logo"
android:layout_gravity="center"
android:layout_margin="3dp"
android:ellipsize="end"
android:gravity="center"
android:lines="2"
android:maxLines="2"
android:padding="2dp"
android:text="نام محصول"
android:textSize="12sp" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"></LinearLayout>
<TextView
android:id="@+id/txt_price"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
android:background="@color/colorAccent"
android:gravity="center_horizontal"
android:padding="3dp"
android:text="۷۵۰۰ ت"
android:textColor="#fff"
android:textSize="12sp" />
</LinearLayout>
</android.support.v7.widget.CardView>
</LinearLayout>

在我的activty,我找到了自己的MyScrollView,并创建了几个MyRecycleView实例并添加到其中!

如果我正确理解了您的问题,那么您不需要执行所有这些操作。 使用NestedScrollView而不是Scrollview

建议:我看了你的视频,你也可以使用嵌套的回收视图来让你的UI完全动态化。RecyclerView非常强大,它的ViewHolders。您可以在父回收器视图的项中添加水平回收器视图,然后在父回收器视图的 onBind 方法中使用适配器初始化内部回收器视图。

最新更新