天天看点

Android 手势(Gesture)——手势检测

手势,其实是指用户手指或触摸笔在触摸屏上的连续触碰行为,比如,在屏幕上从左到右划出的一个动作,就是手势。再比如在屏幕上画出一个圆圈也是手势。

手势这种连续的触碰会形成某个方向上的移动趋势,也会形成一个不规则的几何图形,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。

Android 手势(Gesture)——手势检测
Android 手势(Gesture)——手势检测

拖动效果(这里不再演示滑动效果^^):

Android 手势(Gesture)——手势检测