前言:GestureDetector该类主要用来处理自定义view或者其他场景的手势处理,该类由Android官方提供,粗解GestureDetector,方便自己巩固学习、后续复习。该篇文章不会过多的展示业务代码,这不是我的目的,主要对如何使用以及使用过程中,需要注意的点进行说明,并不是一篇攻略文,仅仅只是一篇描述文
如何使用
分两种情况来示例
如果只想处理双击,也需要实现 OnGestureListener 以及 OnDoubleTapListener,需要在 OnGestureListener监听的 onDown 方法中返回true消费事件。
1、只需要处理手势,不需要处理双击
class GestureView(context: Context, attrs: AttributeSet?) : View(context, attrs),
GestureDetector.OnGestureListener {
private val gestureDetector = GestureDetectorCompat(context, this)
override fun onTouchEvent(event: MotionEvent): Boolean {
return gestureDetector.onTouchEvent(event)
}
override fun onDown(e: MotionEvent): Boolean {
//这里必须返回true,不然后续监听不会收到事件,等同于在ACTION_DOWN中返回true
//有一种写法是
return e.actionMasked == MotionEvent.ACTION_DOWN
//但大多数情况,直接返回true即可
return true
}
//显示按下效果,忽略父布局是不是滑动布局的影响,用户触摸到并且触摸时间到了100ms显示按下效果,
override fun onShowPress(e: MotionEvent?) {
}
//处理单击,(如果gesture支持长按,那么只有在长按时间500毫秒内抬起才会被调用)
override fun onSingleTapUp(e: MotionEvent?): Boolean {
//返回true代表消费了这个点击事件,该返回值用于给系统做记录,对事件序列不会产生影响
return false
}
//处理滑动,接收到的事件序列是ACTION_MOVE,
//distanceX 与 distanceY 是这次事件跟上次事件的触摸点的距离,数值是用旧的触摸点减去新的触摸点得到
override fun onScroll(
downEvent: MotionEvent,
currentEvent: MotionEvent,
distanceX: Float,
distanceY: Float
): Boolean {
return false
}
//长按
override fun onLongPress(e: MotionEvent?) {
}
//快速滑动view后松手触发,处理快滑/惯性滑动后的后续操作,跟onScroll配合使用,
//velocityX velocityY 数值代表速率,单位时间内的位移
override fun onFling(
e1: MotionEvent?,
e2: MotionEvent?,
velocityX: Float,
velocityY: Float
): Boolean {
return false
}
}
2、需要手势,也需要处理双击
class GestureView(context: Context, attrs: AttributeSet?) : View(context, attrs),
GestureDetector.OnDoubleTapListener, GestureDetector.OnGestureListener {
private val gestureDetector = GestureDetectorCompat(context, this)
override fun onTouchEvent(event: MotionEvent): Boolean {
return gestureDetector.onTouchEvent(event)
}
override fun onSingleTapConfirmed(e: MotionEvent): Boolean {
return false
}
override fun onDoubleTap(e: MotionEvent?): Boolean {
return false
}
override fun onDoubleTapEven t(e: MotionEvent?): Boolean {
return false
}
override fun onDown(e: MotionEvent): Boolean {
//这里必须返回true,不然后续监听不会收到事件,等同于在ACTION_DOWN中返回true
//有一种写法是
return e.actionMasked == MotionEvent.ACTION_DOWN
//但大多数情况,直接返回true即可
return true
}
//显示按下效果,忽略父布局是不是滑动布局的影响,用户触摸到并且触摸时间到了100ms显示按下效果,
override fun onShowPress(e: MotionEvent?) {
}
//处理单击,(如果gesture支持长按,那么只有在长按时间500毫秒内抬起才会被调用)
override fun onSingleTapUp(e: MotionEvent?): Boolean {
//返回true代表消费了这个点击事件,该返回值用于给系统做记录,对事件序列不会产生影响
return false
}
//处理滑动,接收到的事件序列是ACTION_MOVE,
//distanceX 与 distanceY 是这次事件跟上次事件的触摸点的距离,数值是用旧的触摸点减去新的触摸点得到
override fun onScroll(
downEvent: MotionEvent,
currentEvent: MotionEvent,
distanceX: Float,
distanceY: Float
): Boolean {
return false
}
//长按
override fun onLongPress(e: MotionEvent?) {
}
//快速滑动view后松手触发,处理快滑/惯性滑动后的后续操作,
//velocityX velocityY 数值代表速率,单位时间内的位移
override fun onFling(
e1: MotionEvent?,
e2: MotionEvent?,
velocityX: Float,
velocityY: Float
): Boolean {
return false
}
}
OnGestureListener方法粗解
1、onDown
view被按下的时候触发,返回true代表消费事件,(view的clickable要为true才能被响应)
onShowPress
显示按下效果,忽略父布局是不是滑动布局的影响,用户触摸到并且触摸时间到了100ms显示按下效果,
onSingleTapUp
处理单击,(如果gesture支持长按,那么只有在长按时间500毫秒内抬起才会被调用)
onScroll
处理滑动,接收到的事件序列是ACTION_MOVE,distanceX 与 distanceY 是这次事件跟上次事件的触摸点的距离,数值是用旧的触摸点减去新的触摸点得到
onFling
快滑后产生的惯性滑动效果,比如列表被快滑,手指已经松开了 但是列表还是会继续滑动一下 velocityX velocityY 数值代表速率,单位时间内的位移
onLongPress
被长按时回调 触发长按的时间是500ms
OnDoubleTapListener方法粗解
- onSingleTapConfirmed 单击,在不是双击的时候触发,当支持双击的时候,使用该方法会比较准确,这里会确保不是双击
- onDoubleTap 连续按下两次触发双击,按下抬起再次按下的时间间隔小于300ms会触发双击效果,有防抖效果(触发时间小于40ms也不会回调)
- onDoubleTapEvent 双击后未松手的事件可以在该方法接收到,比如双击之后旋转view.
OnContextClickListener方法粗解
- 等同于鼠标右键
SimpleOnGestureListener类粗解
public static class SimpleOnGestureListener implements OnGestureListener, OnDoubleTapListener,
OnContextClickListener {
public boolean onSingleTapUp(MotionEvent e) {
return false;
}
public void onLongPress(MotionEvent e) {
}
public boolean onScroll(MotionEvent e1, MotionEvent e2,
float distanceX, float distanceY) {
return false;
}
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
float velocityY) {
return false;
}
public void onShowPress(MotionEvent e) {
}
public boolean onDown(MotionEvent e) {
return false;
}
public boolean onDoubleTap(MotionEvent e) {
return false;
}
public boolean onDoubleTapEvent(MotionEvent e) {
return false;
}
public boolean onSingleTapConfirmed(MotionEvent e) {
return false;
}
public boolean onContextClick(MotionEvent e) {
return false;
}
}
当您只想收听所有手势的一个子集时,可以使用这个类。 这实现了OnGestureListener
,OnDoubleTapListener
、OnContextClickListener
中的所有方法, 不执行任何操作并返回false