人生和游戏一样,需要不断的打怪升级,等到了一定的等级,也就打开了新的天地!
1、简介
Android手势常见的有单击、双击、长按、滑动、快速滑动、上滑、下滑、左滑、右滑等等。
我们一般重写View的onTouchEvent(MotionEvent event)然后做一些处理。基本的代码格式:
@Override
public boolean onTouchEvent(MotionEvent event) {
int action = event.getActionMasked();
switch (action) {
case MotionEvent.ACTION_DOWN:
//逻辑处理
break;
case MotionEvent.ACTION_MOVE:
//逻辑处理
break;
case MotionEvent.ACTION_UP:
//逻辑处理
break;
default:
break;
}
return true;
}
这一部分代码的处理基本是一致的。于是强大的谷歌提供了GestureDetector类来简化我们对手势的处理。
下面我们来看看手势开发的API
2、API介绍
手势开发涉及的API
- GestureDetector(手势管理器)
- GestureDetector.OnGestureListener(接口,提供一些回调的手势方法)
- GestureDetector.OnDoubleTapListener(接口,提供一些回调的手势方法)
- GestureDetector.OnContextClickListener(接口,提供一些回调的手势方法)
- GestureDetector.SimpleOnGestureListener(空实现了上面的三个手势接口,供开发者重写指定的手势方法)
2.1、GestureDetector API
手势追踪管理器
- 构造方法
public GestureDetector(Context context, OnGestureListener listener)
public GestureDetector(Context context, OnGestureListener listener, Handler handler)
public GestureDetector(Context context, OnGestureListener listener, Handler handler,
boolean unused)
构造方法最终都走到了四个参数的构造方法。
参数:context //上下文,基本都要传入的参数
参数:OnGestureListener //传入一个手势回调接口
参数:handler //可以改变内部handler的Looper,下一篇原理篇讲解
参数:unused //这个参数目前源码中没有用到
- 对外方法
isLongpressEnabled() //是否支持长按手势
setIsLongpressEnabled(boolean isLongpressEnabled)//设置是否允许长按操作
setOnDoubleTapListener(OnDoubleTapListener onDoubleTapListener)//配置这个接口中支持的手势,下面可以看这个接口支持的手势方法
setContextClickListener(OnContextClickListener onContextClickListener)//配置这个接口中支持的手势,下面可以看这个接口支持的手势方法
onTouchEvent(MotionEvent ev)//核心方法,处理各种手势的逻辑在这个里面
2.2、GestureDetector.OnGestureListener
boolean onDown(MotionEvent e)// 用户按下触发,ACTION_DOWN事件,一次手势过程中触发一次
void onShowPress(MotionEvent e)//用户按下但是没有发生move和up,给用户一个可视化的反馈方法,一次手势过程中触发一次
onLongPress(MotionEvent e)//长按事件
onSingleTapUp(MotionEvent e)//单击事件,这个事件发生了,可能会发生双击事件
onFling(MotionEvent e1, MotionEvent e2, float velocityX,float velocityY) //快速滑动事件
参数:e1:快速滑动第一个DOWN事件 e2:触发快速滑动的move时间 velocityX:快速滑动事件x方向的速度,单位是px/s,就是每秒划过了多少的像素 velocityY:y方向的速度和x含义一致。
boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY)//滑动事件,滑动过程会频繁调用
参数:e1:开始滑动第一个DOWN事件 e2:当前的滑动事件 distanceX:前后两次滑动事件x方向的变化值 distanceY:前后两次滑动事件y方向的变化值
2.3、GestureDetector.OnDoubleTapListener
boolean onSingleTapConfirmed(MotionEvent e)//严格的单击事件,这个事件发生了就不可能会发生双击事件
boolean onDoubleTap(MotionEvent e)//双击事件
boolean onDoubleTapEvent(MotionEvent e)//发生了双击事件,在双击期间ACTION_DOWN、ACTION_MOVE、ACTION_UP都会触发此回调
2.4、GestureDetector.SimpleOnGestureListener
对上面三个接口进行了空实现,手势监听推荐使用这个实现类,这样我们去重写我们需要的手势方法,就不需要每一个手势方法都重写了
3、使用
步骤:
1、构建GestureDetector
2、接管View的onTouchEvent事件处理
示例:
public class MyTestView extends AppCompatImageView {
private static final String TAG = "MyTestView";
private GestureDetector gestureDetector;
public MyTestView(Context context) {
super(context);
init();
}
public MyTestView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public MyTestView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
private void init() {
//1、构建GestureDetector对象,传入需要回调的手势接口,这里我们传入手势接口实现类SimpleOnGestureListener
gestureDetector = new GestureDetector(getContext(), new GestureDetector.SimpleOnGestureListener() {
@Override
public boolean onDown(MotionEvent e) {
Log.d(TAG, "onDown()");
//此处必须返回true,否则就只能触发这个事件和onLongPress()事件了
//其他的事件都不会触发了,这个和android的事件分发机制有关,后面会写一篇关于事件分发。
return true;
}
@Override
public void onLongPress(MotionEvent e) {
super.onLongPress(e);
Log.d(TAG, "onLongPress()");
}
@Override
public boolean onSingleTapUp(MotionEvent e) {
Log.d(TAG, "onSingleTapUp()");
return super.onSingleTapUp(e);
}
@Override
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
Log.d(TAG, "onScroll() distanceX:" + distanceX + ",distanceY:" + distanceY);
ViewGroup viewGroup = (ViewGroup) getParent();
viewGroup.scrollBy((int) distanceX, (int) distanceY);
return true;
}
@Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
Log.d(TAG, "onFling()");
return super.onFling(e1, e2, velocityX, velocityY);
}
});
}
@Override
public boolean onTouchEvent(MotionEvent event) {
//2、调用gestureDetector.onTouchEvent(event)来接管view的onTouchEvent
return gestureDetector.onTouchEvent(event);
}
}
4、手势开发注意点
- 手势方法中凡是有返回值的方法,这些方法的结果都会返回到view的onTouchEvent方法中,有些方法会影响view的事件分发。
- onDown方法要返回true,否则就只能触发onDown和onLongPress事件了,其他的都触发不了了,原因就是影响了事件分发过程。
- onSingleTapUp和onSingleTapConfirmed的区别:
都理解是单击事件,onSingleTapUp事件发生了,后面还是可能会触发onDoubleTap双击事件;而onSingleTapConfirmed发生就是严格的单击事件后面不会发生onDoubleTap了。所以对于严格的单击事件应该重写onSingleTapConfirmed方法
网友评论