1外部拦截法 需要在父容器中重写onInterceptTouchEvent() //处理滑动冲突: 外部拦截法 //所有点击事件均经过父容器处理,如果父容器需要就拦截,否则就不拦截 boolean needEvent;//是否需要处理此事件 @Override public boolean onInterceptTouchEvent(MotionEvent ev) { boolean intercepted = false; switch (ev.getAction()) { case MotionEvent.ACTION_DOWN: intercepted = false; break; case MotionEvent.ACTION_MOVE: if (needEvent) { intercepted = true; } else { intercepted = false; } break; case MotionEvent.ACTION_UP: intercepted = false; break; } return intercepted; } 二 内部拦截法//重写在父类中的方法 @Override public boolean onInterceptTouchEvent(MotionEvent ev) { if (ev.getAction() == MotionEvent.ACTION_DOWN) { return false; } else { return true; } } //重写子类中的方法 boolean needEvent;//是否需要处理此事件 //内部拦截法: 父类默认拦截除了DOWN以外的所有事件 //在子类中默认让父类不拦截任何事件,然后子类拦截自己需要的事件 //再将不需要的事件让父类拦截 @Override public boolean dispatchTouchEvent(MotionEvent ev) { switch (ev.getAction()) { case MotionEvent.ACTION_DOWN: //让父类不拦截任何事件 getParent().requestDisallowInterceptTouchEvent(true); break; case MotionEvent.ACTION_MOVE: if (needEvent) { getParent().requestDisallowInterceptTouchEvent(true); } else { getParent().requestDisallowInterceptTouchEvent(false); } break; case MotionEvent.ACTION_UP: break; } return super.dispatchTouchEvent(ev); } 实例 两个ScrollView的时候,一个可以垂直滑动,一个可以水平滑动,垂直滑动的嵌套水平滑动的, 此时在可以水平滑动的ScrollView中做竖直滑动,会发现外面的可以竖直滑动的ScrollView不会滑动,此时 出现了滑动冲突,可以自定义ScrollView来解决这个冲突 无滑动冲突的ScrollView,采用外部拦截法/** * Created by Venn on 2016/4/8. * 竖直滑动的ScrollView并且里面可以嵌套水平滑动的ScrollView * 且不会引起滑动冲突 */ public class OutScrollView extends LinearLayout { private Context mContext; private Scroller mScroller; private int lastX; private int lastY; private int judgeX; private int judgeY; public OutScrollView(Context context) { this(context, null); } public OutScrollView(Context context, AttributeSet attrs) { super(context, attrs); mContext = context; init(); } private void init() { mScroller = new Scroller(mContext); } @Override protected void onLayout(boolean changed, int l, int t, int r, int b) { super.onLayout(changed, l, t, r, b);//使用父类的布局方法 } @Override public boolean onInterceptTouchEvent(MotionEvent ev) { boolean intercepted = false; int x = (int) ev.getRawX(); int y = (int) ev.getRawY(); switch (ev.getAction()) { case MotionEvent.ACTION_DOWN: intercepted = false; judgeX = x; judgeY = y; if (!mScroller.isFinished()) {//如果一次滑动没处理完,再次按下,则放弃上次滑动,并且将后续事件交给自己处理 mScroller.abortAnimation(); intercepted = true; } break; case MotionEvent.ACTION_MOVE: int dX = x - judgeX; int dY = y - judgeY; if (Math.abs(dX) > Math.abs(dY)) {//如果水平滑动的距离大于竖直滑动的距离,就认为是水平滑动,否则就是竖直滑动 intercepted = false; } else { intercepted = true; } break; case MotionEvent.ACTION_UP: intercepted = false; break; } judgeX = x; judgeY = y; lastX = x; lastY = y; return intercepted; } @Override public boolean onTouchEvent(MotionEvent event) { int x = (int) event.getRawX(); int y = (int) event.getRawY(); switch (event.getAction()) { case MotionEvent.ACTION_DOWN: lastX = x; lastY = y; if (!mScroller.isFinished()) { mScroller.abortAnimation(); } break; case MotionEvent.ACTION_MOVE: int dX = x - lastX; int dY = y - lastY; scrollBy(0, -dY);//因为只处理竖直滑动,所以水平方向默认为0 break; case MotionEvent.ACTION_UP: break; } lastX = x; lastY = y; return true; } }
Android中滑动冲突的解决方案
最新推荐文章于 2024-05-11 17:18:15 发布