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()等方法来获取坐标后进行判断处理。
文章图片
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()为“拖动”或“滑动”的过程中不断触发,直到动作结束,无论快慢都会触发。
推荐阅读
- Quartz|Quartz 源码解析(四) —— QuartzScheduler和Listener事件监听
- 演讲手势
- vue_day05
- 锦囊26(手势动画打造微信页眉的GIF动图)
- linux监听蒲公英线程,重启
- SwiftUI|SwiftUI Button监听点击和释放消息 实现照片切换 (教程含源码 技术大全)
- iOS横向滚动的scrollView和系统pop手势返回冲突的解决办法
- IOS|IOS swift设置通知、监听事件
- JS深挖(事件机制答疑——注册事件监听、事件响应操作、冒泡和捕获)
- Vue计算属性和监听属性