zoukankan      html  css  js  c++  java
  • Android 手势&触摸事件

    在刚开始学Android的时候,就觉得Google的文档不咋样,在研究手势时,更加的感觉Google的文档写得实在是太差了。很多常量,属性和方法,居然连个描述都没有。
    没有描述也就罢了,但是OnGestureListener里手势这么多,它也没有一个介绍说明,在没有进行不断才尝试之前,谁能搞懂onLongPress和onShowPress,
    onScroll和onFling的关系与差别吗?Google真的需要在文档方面做一次大手术了。不过好在经过鄙人不断反复的尝试。从个人的角度为这几个手势动作做出了定义。

    按下(onDown): 刚刚手指接触到触摸屏的那一刹那,就是触的那一下。 
    抛掷(onFling): 手指在触摸屏上迅速移动,并松开的动作。 
    长按(onLongPress): 手指按在持续一段时间,并且没有松开。 
    滚动(onScroll): 手指在触摸屏上滑动。 
    按住(onShowPress): 手指按在触摸屏上,它的时间范围在按下起效,在长按之前。 
    抬起(onSingleTapUp):手指离开触摸屏的那一刹那。 
      除了这些定义之外,鄙人也总结了一点算是经验的经验吧,在这里和大家分享一下。

    任何手势动作都会先执行一次按下(onDown)动作。 
    长按(onLongPress)动作前一定会执行一次按住(onShowPress)动作。 
    按住(onShowPress)动作和按下(onDown)动作之后都会执行一次抬起(onSingleTapUp)动作。 
    长按(onLongPress)、滚动(onScroll)和抛掷(onFling)动作之后都不会执行抬起(onSingleTapUp)动作。

    Android识别触摸屏手势使得用户体验大大提高。在View类中有个View.OnTouchListener内部接口,通过重写他的onTouch(View v, MotionEvent event)方法,我们可以处理一些简单的touch事件,但是这个方法并不能识别手势,如果需要处理一些复杂的手势,用这个接口就会很麻烦(因为我们要自己根据用户触摸的轨迹去判断是什么手势)。好在android为我们提供了GestureDetector类,通过它,我们可以轻松的进行手势识别。下面我做一个简要地介绍。
    一.GestureDetector简介
    1.组成
    GestureDetector类用来识别触摸屏的各种手势,它包含了两个接口和一个内部类:
    接口:
    OnGestureListener:用来监听手势事件(6种)。
    OnDoubleTapListener:用来监听双击事件。
    内部类:
    SimpleOnGestureListener:用来监听所有的手势。实际上它实现了上述两个接口,不过方法体是空的,需要我们自己写。我们可以继承这个类,重写里面的方法进行手势处理。
    2.构造
    GestureDetector gestureDetector=new GestureDetector(GestureDetector.OnGestureListener listener);
    GestureDetector gestureDetector=new GestureDetector(Context context,GestureDetector.OnGestureListener listener);
    GestureDetector gestureDetector=new GestureDetector(Context context,GestureDetector.SimpleOnGestureListener listener);
    3.方法
    (1)onTouchEvent(MotionEvent ev) 分析捕捉到的触摸事件触发相应的回调函数
    (2)setIsLongpressEnabled(boolean isLongpressEnabled) 设置“长按”是否可用
    (3)setOnDoubleTapListener(GestureDetector.OnDoubleTapListener onDoubleTapListener) 设置双击监听器
    4.使用
    流程:
    首先,系统捕捉屏幕的触摸事件(onTouchListener),这时还未涉及具体手势,只是简单地捕捉到触摸。
    接着,在onTouch()方法中调用GestureDetector的onTouchEvent()方法,将捕捉到的MotionEvent交给GestureDetector来处理
    最后,还需要实现抽象方法。
    实现:
    (1)在Activity中创建GestureDetector实例gestureDetector。
    (2)可根据需要选择:
    重写OnGestureListener并通过构造函数传入gestureDetector
    重写OnDoubleTapListener并通过GestureDetector.setOnDoubleTapListener方法传入gestureDetector
    重写SimpleOnGestureListener并通过构造函数传入gestureDetector
    (3)重写Activity的onTouchEvent方法,将所有的触摸事件交给gestureDetector来处理
    @Override
    public boolean onTouchEvent(MotionEvent event) {
    return gestureDetector.onTouchEvent(event);
    }
    二.onGestureListener
    1.onGestureListener识别6种手势,分别是:
    (1) onDown(MotionEvent e):down事件;
    (2) onSingleTapUp(MotionEvent e):一次点击up事件;
    (3) onShowPress(MotionEvent e):down事件发生而move或则up还没发生前触发该事件;
    (4) onLongPress(MotionEvent e):长按事件;
    (5) onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY):滑动手势事件;
    (6) onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY):在屏幕上拖动事件。
    这里我需要啰嗦在网上搜到的关于onFling和onScroll的一点区别。
    onFling()是甩,这个甩的动作是在一个MotionEvent.ACTION_UP(手指抬起)发生时执行,而onScroll(),只要手指移动就会执行。他不会执行MotionEvent.ACTION_UP。onFling通常用来实现翻页效果,而onScroll通常用来实现放大缩小和移动。
    2.重写
    OnGestureListener onGestureListener=new OnGestureListener(){
    @Override
    public boolean onDown(MotionEvent e) {
    return false;
    }
    @Override
    public boolean onFling(MotionEvent e1, MotionEvent e2,
    float velocityX, float velocityY) {
    return false;
    }
    @Override
    public boolean onLongPress(MotionEvent e) {
    return false;
    }
    @Override
    public boolean onScroll(MotionEvent e1, MotionEvent e2,
    float distanceX, float distanceY) {
    return false;
    }
    @Override
    public void onShowPress(MotionEvent e) {

    }
    @Override
    public boolean onSingleTapUp(MotionEvent e) {
    return false;
    }
    }
    可以根据需要,在函数里添加具体的处理方法.之后通过构造函数传入GestureDetector即可。
    GestureDetector gestureDetector=new GestureDetector(this,onGestureListener);
    二.OnDoubleTapListener
    1.OnDoubleTapListener是用来检测鼠标双击事件的。需要实现的抽象方法有:
    (1) onDoubleTap(MotionEvent e):双击事件。
    (2) onDoubleTapEvent(MotionEvent e):双击间隔中还发生其他的动作。通知DoubleTap手势中的事件,包含down、up和move事件
    (这里指的是在双击之间发生的事件,例如在同一个地方双击会产生DoubleTap手势,而在DoubleTap手势里面还会发生down和up事件,这两个事件由该函数通知);
    (3) onSingleTapConfirmed(MotionEvent e):单击事件。用来判定该次点击是SingleTap而不是DoubleTap,如果连续点击两次就是DoubleTap手势,
    如果只点击一次,系统等待一段时间后没有收到第二次点击则判定该次点击为SingleTap而不是DoubleTap,然后触发SingleTapConfirmed事件。
    关于onSingleTapConfirmed和onSingleTapUp的一点区别: OnGestureListener有这样的一个方法onSingleTapUp,和onSingleTapConfirmed容易混淆。
    二者的区别是:onSingleTapUp,只要手抬起就会执行,而对于onSingleTapConfirmed来说,如果双击的话,则onSingleTapConfirmed不会执行。
    2.重写
    OnDoubleTapListener onDoubleTapListener new OnDoubleTapListener() {
    @Override
    public boolean onSingleTapConfirmed(MotionEvent e) {
    return false;
    }
    @Override
    public boolean onDoubleTapEvent(MotionEvent e) {
    return false;
    }
    @Override
    public boolean onDoubleTap(MotionEvent e) {
    return false;
    }
    )
    可以根据需要,在函数里添加具体的处理方法.,之后通过setOnDoubleTapListener传入GestureDetector即可。
    gestureDetector.setOnDoubleTapListener(onDoubleTapListener) ;
    三.SimpleOnGestureListener
    SimpleOnGestureListener是GestureDetector类的一个内部类,该类是static class,也就是说它实际上是一个外部类。可以在外部继承这个类,重写里面的手势处理方法。
    1.SimpleOnGestureListener实际上实现了OnGestureListener 和OnDoubleTapListener,所以它可以完成以上提到的所有手势识别(9种),如上介绍。
    2.重写
    public class simpleOnGestureListener extends SimpleOnGestureListener {

    @Override
    public boolean onDoubleTap(MotionEvent e) {
    return super.onDoubleTap(e);
    }
    @Override
    public boolean onDoubleTapEvent(MotionEvent e) {
    return super.onDoubleTapEvent(e);
    }
    @Override
    public boolean onDown(MotionEvent e) {
    return super.onDown(e);
    }
    @Override
    public boolean onFling(MotionEvent e1, MotionEvent e2, float x,
    float y) {
    return super.onFling(e1, e2, x, y);
    }
    @Override
    public void onLongPress(MotionEvent e) {
    super.onLongPress(e);
    }
    @Override
    public boolean onScroll(MotionEvent e1, MotionEvent e2, float x,
    float y) {
    return super.onScroll(e1, e2, x, y);
    }
    @Override
    public void onShowPress(MotionEvent e) {
    super.onShowPress(e);
    }
    @Override
    public boolean onSingleTapConfirmed(MotionEvent e) {
    return super.onSingleTapConfirmed(e);
    }
    @Override
    public boolean onSingleTapUp(MotionEvent e) {
    return super.onSingleTapUp(e);
    }
    }
    可以根据需要,在函数里添加具体的处理方法,之后通过构造函数传入GestureDetector即可。
    GestureDetector gestureDetector=new GestureDetector(this,simpleOnGestureListener );
    四.另一种思路
    要实现捕捉屏幕手势,除了在Activity中创建gestureDetector外,还有一种思路:构建一个Overlay,这个Overlay实现OnGestureListener接口,使其维护自己的GestureDetector。
    在主视图上添加这个Overlay,并传入相应的listener,即可实现捕捉手势的功能。

    转载,原文地址:http://blog.csdn.net/song_shi_chao/article/details/8224742

  • 相关阅读:
    【面积并】 Atlantis
    【动态前k大 贪心】 Gone Fishing
    【复杂枚举】 library
    【双端队列bfs 网格图建图】拯救大兵瑞恩
    【奇偶传递关系 边带权】 奇偶游戏
    【权值并查集】 supermarket
    CF w4d3 A. Pythagorean Theorem II
    CF w4d2 C. Purification
    CF w4d2 B. Road Construction
    CF w4d2 A. Cakeminator
  • 原文地址:https://www.cnblogs.com/bingyeh/p/7138061.html
Copyright © 2011-2022 走看看