GestureDetector|GestureDetector 手势监听类小记

1、常规的点击滑动的事件处理
设置一些监听器、如button、seekBar 等的onClickListener() onScrollLisrener() onLongClickListener() setOnKeyListener()等等。。。。可以进行一些常规的 点击事件的处理。
2、当我们进行一些复杂的手势 处理的时候 常规的监听器就不够用了
我们可以通过MotionEvent的getAction()方法来获取Touch事件的类型,包括 ACTION_DOWN(按下触摸屏), ACTION_MOVE(按下触摸屏后移动受力点), ACTION_UP(松开触摸屏)和ACTION_CANCEL(不会由用户直接触发)。借助对于用户不同操作的判断,结合getRawX()、getRawY()、getX()和getY()等方法来获取坐标后进行判断处理。

GestureDetector|GestureDetector 手势监听类小记
文章图片
9{_HZW4Z1PSN~(SXG0Y)}OK.png 【GestureDetector|GestureDetector 手势监听类小记】3)使用GestureDetector类来处理 手势
private GestureDetector mGestureDetector = new GestureDetector(getApplicationContext(), mGestureListener);

private GestureDetector.SimpleOnGestureListener mGestureListener = new GestureDetector.SimpleOnGestureListener() { @Override public boolean onDown(MotionEvent e) { L.i("mGestureListener onDown"); onDownHasDone = false; if (idIncludeHkList.getVisibility() == View.VISIBLE) { idIncludeHkList.setVisibility(View.INVISIBLE); onDownHasDone = true; return true; } if (idPlayChatLl.getVisibility() == View.VISIBLE) { dismissChat(); onDownHasDone = true; return true; } if (webView.getVisibility() == View.VISIBLE) { lastLp = (RelativeLayout.LayoutParams) idIvVp.getLayoutParams(); } return super.onDown(e); }@Override public void onLongPress(MotionEvent e) { super.onLongPress(e); if (Constant.DEBUG) L.i("长按"); if (webView.getVisibility() != View.VISIBLE) { otherView.setVisibility(otherView.getVisibility() == View.VISIBLE ? View.INVISIBLE : View.VISIBLE); idPlayGxbTb.setText(""); } }@Override public boolean onSingleTapConfirmed(MotionEvent e) { if (webView.getVisibility() == View.VISIBLE) { disWebView(); return true; } else { if (curView instanceof RelativeLayout && notPlay) { return true; } else { if (notPlay && idPlayRestartIv != null && idPlayRestartIv.getVisibility() != View.VISIBLE && idPlayBufferRl != null && idPlayBufferRl.getVisibility() != View.VISIBLE) { showPlayRestartIv(); } } } return super.onSingleTapConfirmed(e); }@Override public boolean onScroll(MotionEvent event1, MotionEvent event2, float distanceX, float distanceY) { if (event1 == null || event2 == null) { return super.onScroll(event1, event2, distanceX, distanceY); } if (webView.getVisibility() == View.VISIBLE) { float mx = event2.getRawX() - event1.getRawX(); float my = event2.getRawY() - event1.getRawY(); if (mx == 0 && my == 0) { return super.onScroll(event1, event2, distanceX, distanceY); } pointC = 1; L.i(String.format(Locale.CHINA, "mGestureListener onScroll distanceX = %f,distanceY = %f,mx = %f,my = %f", distanceX, distanceY, mx, my)); if (lastLp == null) { L.i("mGestureListener lastLp == null"); lastLp = (RelativeLayout.LayoutParams) idIvVp.getLayoutParams(); } moveView(idPlVv, lastLp.rightMargin - (int) mx, lastLp.bottomMargin - (int) my); moveView(idIvVp, lastLp.rightMargin - (int) mx, lastLp.bottomMargin - (int) my); } else if (direction == 0) { if (ViewUtil.inRangeOfView(idPlayChatContentLv, event1)) { direction = 3; } else { float a = Math.abs(distanceY); float b = Math.abs(distanceX); if (a > b) { direction = 1; // 上下滑动 } else if (b > a) { direction = 2; // 左右滑动 } } } return super.onScroll(event1, event2, distanceX, distanceY); }@Override public boolean onFling(MotionEvent event1, MotionEvent event2, float velocityX, float velocityY) { L.i("onFling"); if (event1 == null || event2 == null) { return super.onFling(event1, event2, velocityX, velocityY); } final int FLING_MIN_DISTANCE = 100, FLING_MIN_VELOCITY = 200; int my = (int) (event2.getY() - event1.getY()); if (event1.getX() - event2.getX() > FLING_MIN_DISTANCE && Math.abs(velocityX) > FLING_MIN_VELOCITY) { // Fling left L.d("Fling left"); // 播放视频的时候调节音量 可以在这里调用方法 } else if (event2.getX() - event1.getX() > FLING_MIN_DISTANCE && Math.abs(velocityX) > FLING_MIN_VELOCITY) { // Fling right L.d("Fling rigth"); } else if (event2.getY() - event1.getY() > FLING_MIN_DISTANCE && Math.abs(velocityY) > FLING_MIN_VELOCITY) { if (direction == 1 && !onDownHasDone) { // Fling down L.d("Fling down"); } } else if (event1.getY() - event2.getY() > FLING_MIN_DISTANCE && Math.abs(velocityY) > FLING_MIN_VELOCITY) { if (direction == 1 && !onDownHasDone) { // Fling up L.d("Fling up"); } } return false; } }; public boolean onTouchEvent(MotionEvent event) { if (event.getAction() == MotionEvent.ACTION_DOWN) { pointC = 0; direction = 0; } int pointCount = event.getPointerCount(); if (pointCount == 1) {// 单一手指在屏幕上时候 if (pointC != 2) return mGestureDetector.onTouchEvent(event); } else { if (pointC != 1)// 这里是缩放 return mScaleGestureDetector.onTouchEvent(event); } return super.onTouchEvent(event); }

另外:在布局中如果有其他需要滑动的控件 例如viewpager 需要etOnTouchListener(listener); 否则可能滑动会失效。因为在上面将触摸事件重写了。
View.OnTouchListener listener = new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
return onTouchEvent(event);
}
};
ps: 在手势检测中,onFling()与onScroll()有点类似,一个为“滑动”,一个为“拖动”。都是手指在屏幕(或某一组件)上移动一段距离后触发。
onFling()为“滑动”的最后触发(即手指Up抬起时触发),需要较为快速的"滑动"操作(但在"滑动"过程中,也会不停的触发onScroll()),如果慢速滑动,最后没有调用onFling()。
onScroll()为“拖动”或“滑动”的过程中不断触发,直到动作结束,无论快慢都会触发。

    推荐阅读