2017-3-6

单点触摸手势识别器GestureDetector

当用户触摸屏幕的时候,会产生许多手势,例如down,up,scroll,filing等。一般情况下,我们可以通过View或Activity的onTouchEvent,或实现OnTouchListener接口后通过onTouch方法,处理一些touch事件,但是这个方法太过简单,如果需要处理一些复杂的手势,用这个接口就会很麻烦(因为我们要自己根据用户触摸的轨迹去判断是什么手势)。为此,Android 给我们提供了GestureDetector类(Gesture:手势,Detector:识别),通过这个类我们可以识别很多的手势。虽然他能识别手势,但是不同的手势要怎么处理,还是给程序员自己要实现的。

注意:
默认情况下,GestureDetector是监听不到MotionEvent事件的,也即GestureDetector的onTouchEvent方法是不会被调用的,若要被调用,可用下面三种方式之一:
  • 如果View【没有】设置OnTouchListener,可以在View的onTouchEvent()方法中将MotionEvent事件传给GestureDetector
  • 如果View设置了OnTouchListener,可以在onTouch()方法中将MotionEvent事件传给GestureDetector
  • 如果View设置了OnTouchListener,并且onTouch()的返回值是false,那么也可以在onTouchEvent()方法中将MotionEvent事件传给GestureDetector;如果onTouch()的返回值是true,那么只能在onTouch()方法中将MotionEvent事件传给GestureDetector
只有这样,GestureDetector注册的OnGestureListener(单击)或OnDoubleTapListener(双击)才能获得完整的MotionEvent事件,进而根据该对象封装的的信息,做出合适的反馈。


GestureDetector:
Detects发现 various gestures and events using the supplied {@link MotionEvent}s. The {@link OnGestureListener} callback will notify users when a particular特殊的 motion event has occurred. This class should only be used with {@link MotionEvent}s reported via touch (don't use for trackball events).  To use this class:
  • Create an instance of the {@code GestureDetector} for your {@link View}
  • In the {@link View#onTouchEvent(MotionEvent)} method ensure you call {@link #onTouchEvent(MotionEvent)}. The methods defined in your callback will be executed when the events occur.
  • If listening for {@link OnContextClickListener#onContextClick(MotionEvent)}  you must call {@link onGenericMotionEvent(MotionEvent)} in {@link View#onGenericMotionEvent(MotionEvent)}.

onTouchEvent:
Analyzes分析 the given motion运动 event and if applicable适合 triggers触发 the appropriate适当的 callbacks on the OnGestureListener supplied提供的.return true if the OnGestureListener consumed销毁 the event, else false.

GestureDetector的回调方法

我们只需要继承SimpleOnGestureListener重载自己需要监听的手势即可。
其中,OnGestureListener的监听事件有:
  • 按下 onDown: 刚刚手指接触到触摸屏的那一刹那,就是触的那一下
  • 抛掷 onFling: 手指在触摸屏上迅速移动,并松开的动作,onDown---onScroll---onScroll---…onFling
  • 长按 onLongPress: 手指按在持续一段时间,并且没有松开
  • 滚动 onScroll: 手指在触摸屏上滑动,onDown---onScroll---onScroll---…onScroll
  • 按住 onShowPress: 手指按在触摸屏上,在按下起效,在长按前失效,onDown->onShowPress->onLongPress
  • 抬起 onSingleTapUp:手指离开触摸屏的那一刹那
OnDoubleTapListener的监听事件有:
  • onDoubleTap,双击的【第二下】down时触发(只执行一次)
  • onDoubleTapEvent,双击的【第二下】down和up都会触发(执行次数不确定)
  • onSingleTapConfirmed,单击确认,即很快的按下并抬起,但并不连续点击第二下

注意:
  • onSingleTapConfirmed和onSingleTapUp都是在down后既没有滑动(onScroll),又没有长按(onLongPress)时, up时触发的
  • 非常快的点击一下:onDown->onSingleTapUp->onSingleTapConfirmed
  • 稍微慢点的点击一下:onDown->onShowPress->onSingleTapUp->onSingleTapConfirmed(最后一个不一定会触发)


OnGestureListener:
The listener that is used to notify when gestures occur. If you want to listen for all the different gestures then implement this interface. If you only want to listen for a subset it might be easier to extend {@link SimpleOnGestureListener}.

OnDoubleTapListener:
The listener that is used to notify when a double-tap or a confirmed single-tap occur.

SimpleOnGestureListener:
public static class SimpleOnGestureListener implements OnGestureListener, OnDoubleTapListener,
OnContextClickListener
A convenience方便的 class to extend when you only want to listen for a subset子集 of all the gestures.
* This implements all methods in the OnGestureListener, OnDoubleTapListener, and OnContextClickListener
* but does nothing and return {@code false} for all applicable methods.


OnGestureListener接口简介
public interface OnGestureListener {
/**
* Notified when a tap occurs with the down {@link MotionEvent} that triggered it. 
* This will be triggered immediately for every down event. All other events should be preceded先于 by this.
* @param e The down motion event.
*/
boolean onDown(MotionEvent e);

/**
* The user has performed执行 a down {@link MotionEvent} and not performed a move or up yet. 
* This event is commonly通常 used to provide visual视觉 feedback反馈 to the user to let them know
* that their action has been recognized验证 i.e. 换言之highlight an element.
* @param e The down motion event
*/
void onShowPress(MotionEvent e);

/**
* Notified when a tap occurs with the up {@link MotionEvent} that triggered it.
* @param e The up motion event that completed the first tap
* @return true if the event is consumed, else false
*/
boolean onSingleTapUp(MotionEvent e);

/**
* Notified when a scroll occurs with the initial on down {@link MotionEvent} and the
* current move {@link MotionEvent}. The distance in x and y is also supplied for convenience遍历.
*
* @param e1 The first down motion event that started the scrolling. 注意e1是不变的
* @param e2 The move motion event that triggered the current当前的 onScroll. 而e2是时刻变的
* @param distanceX The distance along the X axis that has been scrolled since the last
* call to onScroll. This is NOT the distance between {@code e1} and {@code e2}.
* @param distanceY The distance along the Y axis that has been scrolled since the last
* call to onScroll. This is NOT the distance between {@code e1} and {@code e2}.
* @return true if the event is consumed, else false
*/
boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY);

/**
* Notified when a long press occurs with the initial on down {@link MotionEvent} that trigged it.
* @param e The initial on down motion event that started the longpress.
*/
void onLongPress(MotionEvent e);

/**
* Notified of a fling投掷 event when it occurs with the initial on down {@link MotionEvent}
* and the matching up {@link MotionEvent}. The calculated velocity计算出的速度 is supplied along
* the x and y axis in pixels per second. 像素/秒
* @param e1 The first down motion event that started the fling.
* @param e2 The move motion event that triggered the current onFling.
* @param velocityX The velocity of this fling measured in pixels per second along the x axis.
* @param velocityY The velocity of this fling measured in pixels per second along the y axis.
* @return true if the event is consumed, else false
*/
boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY);
}
2017-3-6

缩放手势识别器ScaleGestureDetector

ScaleGestureDetector是Android2.2中增加的类,用于处理缩放手势的工具类,用法与GestureDetector类似,都是通过onTouchEvent()关联相应的MotionEvent。ScaleGestureDetector能使 Views 通过接收到的MotionEvent检测包括多点触摸在内的手势变化信息,当检测到此类信息后,监听器OnScaleGestureListener便会调用相应的回调方法通知用户。

ScaleGestureDetector中定义的公共方法:
  • public float getCurrentSpan() 返回手势过程中,组成该手势的两个触点的当前距离。Return the average distance between each of the pointers forming the gesture in progress through the focal point.焦点
  • public long getEventTime() 返回事件被捕捉时的时间。
  • public float getFocusX() 返回当前手势焦点的 X 坐标。如果手势正在进行中,焦点位于组成手势的两个触点之间。 如果手势正在结束,焦点为仍留在屏幕上的触点的位置。若 isInProgress() 返回 false,该方法的返回值未定义。 Get the X coordinate of the current gesture's focal point. If a gesture is in progress, the focal point is between each of the pointers forming the gesture. If isInProgress() would return false, the result of this function is undefined.
  • public float getPreviousSpan() 返回手势过程中,组成该手势的两个触点的前一次距离。Return the previous average distance between each of the pointers forming the gesture in progress through the focal point.
  • public float getScaleFactor() 返回从前一个伸缩事件至当前伸缩事件的伸缩比率。Return the scaling factor from the previous scale event to the current event。该值定义为  getCurrentSpan() / getPreviousSpan()。
  • public long getTimeDelta() 返回前一次接收到的伸缩事件距当前伸缩事件的时间差,以毫秒为单位。Return the time difference in milliseconds between the previous accepted scaling event and the current scaling event.
  • public boolean isInProgress() 如果手势处于进行过程中,返回 true。Returns true if a scale gesture is in progress.
注意,ScaleGestureDetector和GestureDetector两个类之间没有一毛钱关系。

ScaleGestureDetector:
Detects scaling比例 transformation变换 gestures using the supplied {@link MotionEvent}s.  The {@link OnScaleGestureListener} callback will notify users when a particular  gesture event has occurred.  

ScaleGestureDetector回调方法

ScaleGestureDetector中的监听器为OnScaleGestureListener ,同样有一个默认实现类SimpleOnScaleGestureListener:
public static class SimpleOnScaleGestureListener implements OnScaleGestureListener
/**
* The listener for receiving notifications when gestures occur.If you want to listen for all the
* different gestures then implement this interface. If you only want to listen for a subset
* it might be easier to extend {@link SimpleOnScaleGestureListener}.
* An application will receive events in the following order顺序:
* One onScaleBegin,Zero or more 零个或多个onScale,One onScaleEnd
*/
public interface OnScaleGestureListener {
/**
* Responds响应 to scaling events for a gesture in progress. Reported by pointer motion.
* @param detector The detector reporting报告 the event - use this to
* retrieve取回 extended延伸的 info about event state.
* @return Whether or not the detector should consider认为、当做 this event as handled. 
* If an event was not handled, the detector will continue to accumulate积累 movement 
* until an event is handled. This can be useful if an application, for example,
* only wants to update scaling factors if the change is greater than 0.01.
*/
public boolean onScale(ScaleGestureDetector detector);

/**
* Responds to the beginning of a scaling gesture. Reported by new pointers going down.
* @param detector The detector reporting the event - use this to
* retrieve extended info about event state.
* @return Whether or not the detector should continue recognizing认出 this gesture. 
* For example, if a gesture is beginning with a focal point outside of a region 
* where it makes sense, this may return false to ignore the rest剩余 of the gesture.
*/
public boolean onScaleBegin(ScaleGestureDetector detector);

/**
* Responds to the end of a scale gesture. Reported by existing pointers going up.
* Once a scale has ended, ScaleGestureDetector.getFocusX() and getFocusY()
* will return focal point of the pointers remaining留在 on the screen.
* @param detector The detector reporting the event - use this to
* retrieve extended info about event state.
*/
public void onScaleEnd(ScaleGestureDetector detector);
}
功能比较单一,就是检测缩放事件的,触发时的触摸点>=2时都可以。
2017-3-6

【手势识别】简介 GestureDetector ScaleGestureDetector的更多相关文章

  1. 手势识别 GestureDetector ScaleGestureDetector

    识别器GestureDetector基本介绍 当用户触摸屏幕的时候,会产生许多手势,例如down,up,scroll,filing等.一般情况下,我们可以通过View或Activity的onTouch ...

  2. 手势识别:GestureDetector

    当用户触摸屏幕的时候,会产生许多手势,例如down,up,scroll,filing等等,我们知道View类有个View.OnTouchListener接口,通过重写他的onTouch(View v, ...

  3. 手势识别官方教程(2)识别常见手势用GestureDetector+手势回调接口/手势抽象类

    简介 GestureDetector识别手势. GestureDetector.OnGestureListener是识别手势后的回调接口.GestureDetector.SimpleOnGesture ...

  4. iOS开发系列--触摸事件、手势识别、摇晃事件、耳机线控

    -- iOS事件全面解析 概览 iPhone的成功很大一部分得益于它多点触摸的强大功能,乔布斯让人们认识到手机其实是可以不用按键和手写笔直接操作的,这不愧为一项伟大的设计.今天我们就针对iOS的触摸事 ...

  5. iOS-触摸事件、手势识别、摇晃事件、耳机线控

    概览 iPhone的成功很大一部分得益于它多点触摸的强大功能,乔布斯让人们认识到手机其实是可以不用按键和手写笔直接操作的,这不愧为一项伟大的设计.今天我们就针对iOS的触摸事件(手势操作).运动事件. ...

  6. Android手势识别(单击 双击 抬起 短按 长按 滚动 滑动)

    对于触摸屏,其原生的消息无非按下.抬起.移动这几种,我们只需要简单重载onTouch或者设置触摸侦听器setOnTouchListener即可进行处理.不过,为了提高我们的APP的用户体验,有时候我们 ...

  7. 转发:iOS开发系列--触摸事件、手势识别、摇晃事件、耳机线控

    -- iOS事件全面解析 转载来自崔江涛(KenshinCui) 链接:http://www.cnblogs.com/kenshincui/p/3950646.html 概览 iPhone的成功很大一 ...

  8. Android手势识别的发展

    在播放器.与手势识别.所以,看看今天的我们Android手势识别. 首先,我们需要站在巨人的肩膀上.有些人举了个例子和说明. 第一章: http://www.2cto.com/kf/201110/10 ...

  9. android 缩放平移自定义View 显示图片

    1.背景 现在app中,图片预览功能肯定是少不了的,用户基本已经形成条件反射,看到小图,点击看大图,看到大图两个手指开始进行放大,放大后,开始移动到指定部位~~~ 我相信看图的整个步骤,大家或者说用户 ...

随机推荐

  1. 有了这套flex页面布局方案,页面什么的,那都不是事。

    一.CSS3弹性盒子弹性盒子是CSS3的一种新布局模式.CSS3 弹性盒( Flexible Box 或 flexbox),是一种当页面需要适应不同的屏幕大小以及设备类型时确保元素拥有恰当的行为的布局 ...

  2. Sting.format字符串格式化

    控制格式scanf printf 也不知道为什么=-= 越研究深层的java就越感觉它是从别的语言那抄袭来的

  3. 数据准备<4>:变量筛选-理论篇

    在上一篇文章<数据准备<3>:数据预处理>中,我们提到降维主要包括两种方式:基于特征选择的降维和基于维度转换的降维,其中基于特征选择的降维通俗的讲就是特征筛选或者变量筛选,是指 ...

  4. BZOJ.3105.[CQOI2013]新Nim游戏(线性基 贪心 博弈论)

    题目链接 如果后手想要胜利,那么在后手第一次取完石子后 可以使石子数异或和为0.那所有数异或和为0的线性基长啥样呢,不知道.. 往前想,后手可以取走某些石子使得剩下石子异或和为0,那不就是存在异或和为 ...

  5. 【推导】【贪心】Codeforces Round #472 (rated, Div. 2, based on VK Cup 2018 Round 2) D. Riverside Curio

    题意:海平面每天高度会变化,一个人会在每天海平面的位置刻下一道痕迹(如果当前位置没有已经刻划过的痕迹),并且记录下当天比海平面高的痕迹有多少条,记为a[i].让你最小化每天比海平面低的痕迹条数之和. ...

  6. 2018-2019-2 20162318《网络攻防技术》Exp5 MSF基础应用

    1.实验内容 1.一个主动攻击实践,如ms08_067 2. 一个针对浏览器的攻击,如ms11_050) 3. 一个针对客户端的攻击,如Adobe 4. 成功应用任何一个辅助模块 2.基础问题回答 2 ...

  7. [BZOJ2716]天使玩偶

    [BZOJ2716]天使玩偶 题目大意: 一个平面直角坐标系,坐标\(1\le x,y\le10^6\).\(n(n\le10^6)\)次操作,操作包含以下两种: 新增一个点\((x,y)\): 询问 ...

  8. poj 3660 Cow Contest Flyod

    Cow Contest Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 5989   Accepted: 3234 Descr ...

  9. [Dynamic Language] Python定时任务框架

    APScheduler是一个Python定时任务框架,使用起来十分方便.提供了基于日期.固定时间间隔以及crontab类型的任务,并且可以持久化任务.并以daemon方式运行应用. 在APSchedu ...

  10. BZOJ2831(小强的金字塔系列问题--区域整点数求法)

    题目:2831: 小强的金字塔 题意就是给出A,B,C,R,L,然后求 这里其实用到扩展欧几里德.(基本上参照clj的解题报告才理解的) 分析:我们先来分析一般情况: 这里我们假设A<C和B&l ...