Android 手势操作GestureDetector

  在很多应用中我们经常会看到一些不同手势的点击事件,例如QQ的消息列表,我们可以通过左滑消息来选择删除或者置顶或者标记为已读,我们也可以通过右滑拖出QQ菜单。有些应用中还会有长按,双击等手势。但是一般情况下,这些操作的手势都不是很复杂,不会出现什么右击左击,或者三连击这样的手势。因为开发应用的原则就是简单化,让别人可以一看就懂,一看就会。
  
  今天我们就来学习一下Android中手势的操作。在Android中手势的操作使用GestureDetector这个类。

GestureDetector概述

  Detects various gestures and events using the supplied MotionEvents. The GestureDetector.OnGestureListener callback will notify users when a particular motion event has occurred. This class should only be used with MotionEvents reported via touch (don’t use for trackball events).

  GestureDetector通过MotionEvent类检测不同的手势和事件。在MotionEvent有很多基础的动作监测:ACTION_CANCEL(动作取消), ACTION_DOWN(按下), ACTION_MOVE(移动),ACTION_UP(抬起)等,而手势的操作就是以MotionEvent中这些基本的动作为基础的,通过将这些基本的动作组合从而形成手势。在GestureDetector中有一个GestureDetector.OnGestureListener监听类,这个类都是当手势发生时调用的。

要使用GestureDetector类,我们首先要创建它的对象,我们先来看他的构造器:
  注意:GestureDetector(GestureDetector.OnGestureListener listener, Handler handler)和GestureDetector(GestureDetector.OnGestureListener listener)在API level 3以后已经取代,这里不再列出。

  • GestureDetector(Context context, GestureDetector.OnGestureListener listener)
      传入两个参数,一个是Context的对象,一个是GestureDetector.OnGestureListener的对象。上面已经讲过GestureDetector.OnGestureListener是什么。
  • GestureDetector(Context context, GestureDetector.OnGestureListener listener, Handler handler)
      前两个不用说了,第三个我查了一下API,原文是这样:”the handler to use for running deferred listener events.”,意思应该是当运行延时的监听对象时使用这个Handler对象。
  • GestureDetector(Context context, GestureDetector.OnGestureListener listener, Handler handler, boolean unused)
      前三个不用说了吧,最后一个是定义当前有没有被使用。
      
      一般情况下我们都是使用第一个构造器。
      
    GestureDetector中的方法不是很多,有两个是非常重要的,我们这里拿出来说一说,其他的看名字就了解如何使用了:
  • onGenericMotionEvent(MotionEvent ev)
      当我们的手势动作是由GenericMotionEvent动作构成时,我们需要调用这个方法,这样我们定义的手势才可用。
  • onTouchEvent(MotionEvent ev)
      当我们的手势是由MotionEvent 构成时,我们需要调用这个方法,手势才能生效。

      我们下面来看一下GestureDetector手势是如何定义的?

GestureDetector.SimpleOnGestureListener

  创建手势,首先要创建一个GestureDetector对象。创建GestureDetector对象时要传入一个GestureDetector.OnGestureListener对象,所以我们要创建一个GestureDetector.OnGestureListener对象,但是GestureDetector.OnGestureListener是一个interface接口,有人可能会想我们可以创建一个GestureDetector.OnGestureListener的匿名内部类啊,这样是可以,但是要实现GestureDetector.OnGestureListener中的好多方法,这样会使我们代码冗长复杂。API中给我们提供了一个解决的方法,就是通过使用GestureDetector.SimpleOnGestureListener类。

  我们看API中对他的描述:A convenience class to extend when you only want to listen for a subset of all the gestures. This implements all methods in the GestureDetector.OnGestureListener, GestureDetector.OnDoubleTapListener, and GestureDetector.OnContextClickListener but does nothing and return false for all applicable methods.

  
  大体意思是这样的:我们可以通过使用这个类来监听一系列的手势操作,也就是我们可以使用这二个监听器监听多个手势,这个类继承了: GestureDetector.OnGestureListener(手势监听器), GestureDetector.OnDoubleTapListener(双击监听器), and GestureDetector.OnContextClickListener(上下文点击监听器)中的所有方法。

我们来看一下他的方法:
onContextClick(MotionEvent e):上下文点击手势。
onDoubleTap(MotionEvent e):双击手势。
onDoubleTapEvent(MotionEvent e):双击按下和抬起分别产生点击事件手势。
onDown(MotionEvent e):单击手势。
onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY):滑动手势,这个要与onScroll区别:onFling是滑动后,事件响应;onScroll是手指滑动时,控件也跟着滑动,同时响应。
onLongPress(MotionEvent e):长按手势。
onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY):拖动手势。
onShowPress(MotionEvent e):按下时响应事件。
onSingleTapConfirmed(MotionEvent e):单击手势。
onSingleTapUp(MotionEvent e):也是单击手势,是单击抬起后响应时间。

手势定义

  前面基础差不多都打好了,下面我们来使用下。这里只练习:双击,滑动和拖动的手势操作。

手势定义 ###  

定义一个MyButton类继承Button控件。

public class MyButton extends Button {
    private GestureDetector mGestureDetector;//定义手势对象
    //自定义View的构造器
    public MyButton(Context context) {
        super(context);
    }
    public MyButton(Context context, AttributeSet attrs) {
        super(context, attrs);
        //初始化GestureDetector对象,传入GestureDetector.SimpleOnGestureListener对象,监听多个手势。
        mGestureDetector = new GestureDetector(context, new GestureDetector.SimpleOnGestureListener() {
            //监听双击手势
            @Override
            public boolean onDoubleTap(MotionEvent e) {              
                Log.d("data", "点击了两次按钮! ");
                return true;
            }
            //监听滑动手势
            @Override
            public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
                if (Math.abs(e2.getX() - e1.getX()) > 0) {
                    //设置控件滑动的动画
                    ObjectAnimator.ofFloat(MyButton.this, "translationX", getTranslationX(), getTranslationX() + (e2.getX() - e1.getX())).setDuration(500)
                            .start();
                    return true;
                }
                return super.onFling(e1, e2, velocityX, velocityY);
            }
            //监听拖动的手势
            @Override
            public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
                //设置控件跟随手势移动
                setTranslationY(getTranslationY() + e2.getY() - e1.getY());
                setTranslationX(getTranslationX() + e2.getX() - e1.getX());
                return true;
            }
        });
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        //调用此方法,实现手势的监听使用。
        mGestureDetector.onTouchEvent(event);
        return super.onTouchEvent(event);
    }
}

  注意:复制代码使用时,onFling方法和onScroll方法不要同时使用,因为效果近似,可能会看不出效果来。使用onFling手势将onScroll方法屏蔽掉,使用onScroll手势时同理。
双击手势:

这里写图片描述

滑动手势:

这里写图片描述

拖动手势:

这里写图片描述

Activity中响应手势事件

  如果我们想在Activity中使用双击,滑动,拖动的点击事件,我们需要在MyButton中定义一个点击事件。这里我们以双击为例,在MyButton中添加如下代码:(这里使用到了自定义View中的自定义点击事件知识点,不懂的可以查看《Android 自定义View——自定义点击事件 》这篇博客。

    //这里其实是使用的自定义View的点击事件
    public OnDoubleClickListerner onDoubleClickListerner;//定义双击的监听接口对象

    //设置获得双击的监听接口对象的set方法。
    public void setOnDoubleClickListerner(OnDoubleClickListerner onDoubleClickListerner) {
        this.onDoubleClickListerner = onDoubleClickListerner;
    }

    //创建双击的监听接口
    interface OnDoubleClickListerner {
        void onDoubleClick(View view);
    }

在双击手势中添加:

            //监听双击手势
            @Override
            public boolean onDoubleTap(MotionEvent e) {
                if (onDoubleClickListerner != null) {
                    onDoubleClickListerner.onDoubleClick(MyButton.this);
                }
                Log.d("data", "点击了两次按钮! ");
                return true;
            }

这样我们就可以在Activity中使用了:

public class MainActivity extends AppCompatActivity {
    private MyButton button;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        button = (MyButton) findViewById(R.id.button);
        button.setOnDoubleClickListerner(new MyButton.OnDoubleClickListerner() {
            @Override
            public void onDoubleClick(View view) {
                Log.d("data", "点击了两次按钮! ");
                //次此处添加处理代码
            }
        });
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小_爽

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值