ScrollView 嵌套ViewPage,如果事件没有传递ViewPage在需要滑动的时候会遇到不流畅的问题,ScrollView 嵌套RecyclerView又会有一个惯性丢失的问题。
解决方法
对于以上两种情况,一个是ScrollView把不该处理的滑动方向处理了,这时候屏蔽一个方向下放到子view处理即可,对于嵌套RecyclerView的则应该完全交由ScrollView处理。单独的例子可以找到很多,这里贴一个自用的两种结合的例子。
需求:ScrollView同时嵌套了ViewPage和RecyclerView,对于左右事件完全交由子View处理,对于竖直事件完全交由ScrollView处理。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67
| import android.content.Context; import android.util.AttributeSet; import android.view.GestureDetector; import android.view.MotionEvent; import android.view.ViewConfiguration; import android.widget.ScrollView;
public class CustomScrollView extends ScrollView { private GestureDetector mGestureDetector; private float downY; private float mTouchSlop;
public CustomScrollView(Context context) { super(context); mGestureDetector = new GestureDetector(context, new YScrollDetector()); setFadingEdgeLength(0); mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop(); }
public CustomScrollView(Context context, AttributeSet attrs) { super(context, attrs); mGestureDetector = new GestureDetector(context, new YScrollDetector()); setFadingEdgeLength(0); mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop(); }
public CustomScrollView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); mGestureDetector = new GestureDetector(context, new YScrollDetector()); setFadingEdgeLength(0); mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop(); }
@Override public boolean onInterceptTouchEvent(MotionEvent e) { int action = e.getAction(); switch (action) { case MotionEvent.ACTION_DOWN: downY = e.getRawY(); break; case MotionEvent.ACTION_MOVE: float moveY = e.getRawY(); if ((Math.abs(moveY - downY) > mTouchSlop) && mGestureDetector.onTouchEvent(e)) { return true; } break; }
return super.onInterceptTouchEvent(e) && mGestureDetector.onTouchEvent(e);
} class YScrollDetector extends GestureDetector.SimpleOnGestureListener { @Override public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) { return Math.abs(distanceY) > Math.abs(distanceX); } } }
|