之前在使用网易新闻的时候,左右滑动页面可以打开和关闭新的页面,对于这个功能一直很喜欢,刚好今天有空,工作不忙,于是就抽空把这个功能写出来了,其实用到的都是很简单的手势监听api,加入了一些判断,核心代码如下:
1、在onInterceptTouchEvent中,判断是否属于滑动(还是无意触碰),是的话,就拦截该touchevent,然后传递给onTouchEvent,不是的话,默认传递给下一层view
@Override public boolean onInterceptTouchEvent(MotionEvent ev) { switch (ev.getAction()) { case MotionEvent.ACTION_DOWN: mDownX = mTempX = (int) ev.getRawX(); mDownY = (int) ev.getRawY(); break; case MotionEvent.ACTION_MOVE: int moveX = (int) ev.getRawX(); // 满足此条件屏蔽SildingFinishLayout里面子类的touch事件 if (Math.abs(moveX - mDownX) > mTouchSlop && Math.abs((int) ev.getRawY() - mDownY) < mTouchSlop) { return true; } break; } return super.onInterceptTouchEvent(ev); }
2、在onTouchEvent中处理滑动事件,在手指离开屏幕的时候,判断滑动距离,如果超过view宽度的1/3,就认为是有效的滑动,用interface回调该事件:
@Override public boolean onTouchEvent(MotionEvent event) { switch (event.getAction()) { case MotionEvent.ACTION_MOVE: int moveX = (int) event.getRawX(); int deltaX = mTempX - moveX; // Log.i("debug", "deltaX:" + deltaX + "mTouchSlop:" + mTouchSlop); mTempX = moveX; if (Math.abs(moveX - mDownX) > mTouchSlop && Math.abs((int) event.getRawY() - mDownY) < mTouchSlop) { isSilding = true; } if (Math.abs(moveX - mDownX) >= 0 && isSilding) { // mContentView.scrollBy(deltaX, 0); totalMoveX += deltaX; } break; case MotionEvent.ACTION_UP: isSilding = false; // Log.i("debug", "TotoalMoveX:" + totalMoveX + "viewVidth:" + viewWidth); if (Math.abs(totalMoveX) >= viewWidth / 3) { if (totalMoveX > 0) { swipeListener.onLeftSwipe(); }else { swipeListener.onRightSwipe(); } } totalMoveX = 0; break; } return true; }
3、最后一步,就是在activity中,引用该回调,事件滑动的监听:
gestureLayout.setSwipeGestureListener(new onSwipeGestureListener() { @Override public void onRightSwipe() { Log.i("debug", "onRightSwipe"); } @Override public void onLeftSwipe() { Log.i("debug", "onLeftSwipe"); } });
到此及可以实现监听手势的滑动了,不过这只是一个简单的demo,有以下两个缺陷,还带优化:
1、如果view里面嵌套的是viewpager,就会导致viewpager无法滑动,因为touch事件被拦截了;
2、如果是listview的话,因为我检测是左右滑动的,因为没有问题,不过没有测试过,不敢保证;
最后,附上源码,供参考