在很多应用中我们经常会看到一些不同手势的点击事件,例如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", "点击了两次按钮! ");                //次此处添加处理代码            }        });    }}

更多相关文章

  1. Android(安卓)面试那些事之Java基础
  2. Android监听事件的回调机制
  3. Android简易手势密码开源库
  4. Android(安卓)UI设计之自定义Dialog,实现各种风格效果的对话框
  5. Android使用Google Map服务 - 根据GPS信息在地图上定位
  6. android 验证码输入框
  7. Android(安卓)监听系统媒体音量变化
  8. Fragment.setArguments()方法向fragment对象传递数据的重要作用
  9. Android使用GestureDetector实现手势滑动效果

随机推荐

  1. android-疑问2
  2. Android(安卓)PhotoView 使用教程
  3. android > 屏蔽掉返回键
  4. android menu自定义菜单 Demo
  5. android 监听其它app的错误或者崩溃的方
  6. android java 文件的读写
  7. Android(安卓)ContextMenu和Listview配合
  8. Android之关于Intent的Flag属性的讲解
  9. How to fix the Android(安卓)AVD no tar
  10. OnclickListener与View.OnclickListener