手势,其实是指用户手指或触摸笔在触摸屏上的连续触碰行为,比如,在屏幕上从左到右划出的一个动作,就是手势。再比如在屏幕上画出一个圆圈也是手势。
手势这种连续的触碰会形成某个方向上的移动趋势,也会形成一个不规则的几何图形,android提供了手势检测,并为两种手势行为都提供了支持:对于第一种,android提供了手势检测,并为手势检测提供了相应的监听器。
对于第二种,Android允许开发者添加手势,并提供了相应的API识别用户手势
GestureDetector.OnGestureListener
1.GestureDetector类:
Android为手势检测提供了一个GestureDetector类,GestureDetector实例代表了一个手势检测器,创建GestureDetector时需要传入一个GestureDetector.OnGestureListener 实例。
GestureDetector.OnGestureListener就是一个监听器,负责对用户手势提供相应。
GestureDetector.OnGestureListener中包含的事件处理方法:
-
boolean onDoubleTap(MotionEvent e)
解释:双击的第二下Touch down时触发
-
boolean onDoubleTapEvent(MotionEvent e)
解释:双击的第二下Touch down和up都会触发,可用e.getAction()区分。
-
boolean onDown(MotionEvent e)
解释:Touch down时触发
-
boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY)
解释:Touch了滑动一点距离后,up时触发。velocityX,是在x轴上滑动的速度。
-
void onLongPress(MotionEvent e)
解释:Touch了不移动一直Touch down时触发
-
boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY)
解释:Touch了滑动时触发。
-
void onShowPress(MotionEvent e)
解释:Touch了还没有滑动时触发
(与onDown,onLongPress比较
onDown只要Touch down一定立刻触发。
而Touchdown后过一会没有滑动先触发onShowPress再是onLongPress。
所以Touchdown后一直不滑动,onDown->onShowPress->onLongPress这个顺序触发。
- boolean onSingleTapConfirmed(MotionEvent e)
-
boolean onSingleTapUp(MotionEvent e)
解释:上面这两个函数都是在touch down后又没有滑动(onScroll),又没有长按(onLongPress),然后Touchup时触发。
-
点击一下非常快的(不滑动)Touchup:
onDown->onSingleTapUp->onSingleTapConfirmed
-
点击一下稍微慢点的(不滑动)Touchup:
onDown->onShowPress->onSingleTapUp->onSingleTapConfirmed
注:
1)由于如果实现监听器,需要重写所有的方法,我们可以发现可以实现GestureDetector下的一个子类SimpleOnGestureListener,然后重写其中的某个方法即可。
2)注意onFling和onSroll的区别。
2.使用步骤:
1)创建GestureDetector对象,必须实现监听器或者创建其下的SimpleOnGestureListener子类的一个匿名内部类。
2)为Activity(偶尔也可以是特定的组件)的TouchEvent时间绑定监听器,在事件处理中指定把Activity(或组件)的TouchEvent事件交给GestureDetector处理:
例:
@Override
public boolean onTouchEvent(MotionEvent event) {
mGesture.onTouchEvent(event);//将手势和按钮绑定
return super.onTouchEvent(event);
}
注意的要点:每个方法中如果要执行,必须return true;
范例:
功能:为按钮添加双击手势,并添加双击的事件。
思路:
手势:
1)定义一个手势变量。
2)new一个手势实例,并在其中添加监听,监听双击事件(),重写其双击的方法onDoubleTap();
3)在onTouch方法中:手势与Button绑定。
添加按钮的双击监听事件:
这是之前将的观察者模式。不再详细介绍喽。
手势中添加滑动,拖动的效果:
onFling()方法实现滑动,仅滑动完才进行动画效果。
onScroll()方法实现跟随拖动,view随手指移动。
下面呈上代码:
主活动:
public class MainActivity extends Activity {
private MyButton button;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
button = (MyButton) findViewById(R.id.buttonGesture);
button.setOnDoubleListener(new MyButton.onDoubleListener() {
@Override
public void onDoubleClickListener(View view) {
Log.d("mytouch","get touch");
}
});
}
}
自定义Button:
public class MyButton extends Button {
private GestureDetector mGesture;
interface onDoubleListener{
public void onDoubleClickListener(View view);
}
private onDoubleListener onDoubleListener;
public MyButton.onDoubleListener getOnDoubleListener() {
return onDoubleListener;
}
public void setOnDoubleListener(MyButton.onDoubleListener onDoubleListener) {
this.onDoubleListener = onDoubleListener;
}
public MyButton(Context context) {
super(context);
}
public MyButton(Context context, AttributeSet attrs) {
super(context, attrs);
//1.new 一个手势,其中创建一个监听事件(不使用原来的返回值)
mGesture = new GestureDetector(context,new GestureDetector.SimpleOnGestureListener(){
@Override
public boolean onDoubleTap(MotionEvent e) {
if(onDoubleListener!=null){
onDoubleListener.onDoubleClickListener(MyButton.this);
}
Log.d("mytouch","double touch");
return true;
}
//手势中来重写方法
//只有手松开时才开始动画效果
// @Override
// public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {//滑动,产生动画效果
// if(Math.abs(e2.getX()-e1.getX())>50){
// Log.d("myfling", "在x轴滑动");
// ObjectAnimator.ofFloat(MyButton.this,"translationX",getTranslationX(),getTranslationX()+e2.getX()-e1.getX()).setDuration(500).start();
// return true;//一定要返回true才执行
// }
// return super.onFling(e1, e2, velocityX, velocityY);
// }
@Override//因为只要手接触屏幕,一直都调用此方法,所以直接set即可产生拖动的效果
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
setTranslationX(getTranslationX()+e2.getX()-e1.getX());
setTranslationY(getTranslationY()+e2.getY()-e1.getY());
return true;//返回true才运行此方法
}
});
});
}
public MyButton(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
mGesture.onTouchEvent(event);//2.将手势和按钮绑定
return super.onTouchEvent(event);
}
}
效果:
双击效果:
双击,打印双击事件的Log和自定义button中手势监听的Log。
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsIyM2cTOxYTN0EDNykDM1EDMy8CX0Vmbu4GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.jpg)
拖动效果(这里不再演示滑动效果^^):