I want to implement an activity that contains a vertical ScrollView
that has several horizontal RecyceViews
as children!
but sometimes I faced to a strange touch interrupts from inner RecycleViews
, when I try to scroll in the vertical direction and my start point of touch is in inside of an item( of RecycleView
) scrolling of ScrollView
doesn't work correctly and it doesn't scroll in Y direction!
I try to implement my own ScrollView
and RecycleView
To handle touch actions but the problem still exists!
you can watch what really happens in this video: video of my applications problem
MyScrollView:
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;
}
}
}
MyRecycleView:
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;
}
}
}
and here is my RecycleView items adapter 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>
And in my activty
I find my MyScrollView
and create several instance of MyRecycleView
and add to it!