文档章节

OnTouchListener与OnGestureListener的区别

gavin_jin
 gavin_jin
发布于 2014/03/09 01:24
字数 897
阅读 5574
收藏 1

Android事件处理机制是基于Listener实现的,比如触摸屏相关的事件,是通过OnTouchListener实现的;而手势是通过OnGestureListener实现的,那么这两者有什么关联呢?

OnTouchListener

OnTouchListener接口中包含一个onTouch()方法,直接看一个例子:

public class MainActivity extends Activity implements OnTouchListener {
	public void onCreate(Bundle outState) {
    	super.onCreate(outState);
    	setContentView(R.layout.main);
    	TextView tv = (TextView) findViewById(R.id.tv);
    	tv.setOnTouchListener(this);
    }

    public boolean onTouch(View v, MotionEvent event) {
    	Toast.makeText(this,  "Touch Touch", Toast.LENGTH_SHORT).show();
		return false ; 
    }
}

我们可以通过MotionEvent的getAction()方法来获取Touch事件的类型,包括 ACTION_DOWN(按下触摸屏), ACTION_MOVE(按下触摸屏后移动受力点), ACTION_UP(松开触摸屏)和ACTION_CANCEL(不会由用户直接触发)。借助对于用户不同操作的判断,结合getRawX()、 getRawY()、getX()和getY()等方法来获取坐标后,我们可以实现诸如拖动某一个按钮,拖动滚动条等功能。

可以看到OnTouchListener只能监听到三种触摸事件,即按下,移动,松开,如果想要监听到双击、滑动、长按等复杂的手势操作,这个时候就必须得用到OnGestureListener了。

OnGestureListener

接着上面的例子,这次加入手势监听:

public class MainActivity extends Activity implements OnTouchListener, OnGestureListener {
	private  GestureDetector mGestureDetector; 

	public void onCreate(Bundle outState) {
    	super.onCreate(outState);
    	setContentView(R.layout.main);

    	mGestureDetector = new GestureDetector(this);
    	TextView tv = (TextView) findViewById(R.id.tv);
    	tv.setOnTouchListener(this);
    }

    public boolean onTouch(View v, MotionEvent event) {
    	return mGestureDetector.onTouchEvent(event);
    }

    // 用户轻触触摸屏,由1个MotionEvent ACTION_DOWN触发  
    public boolean onDown(MotionEvent arg0) {
		Log.i("MyGesture", "onDown");
		Toast.makeText(this, "onDown", Toast.LENGTH_SHORT).show();      
		return true;
	}

	// 用户轻触触摸屏,尚未松开或拖动,由一个1个MotionEvent ACTION_DOWN触发, 注意和onDown()的区别,强调的是没有松开或者拖动的状态
	public void onShowPress(MotionEvent e) {
		Log.i("MyGesture",  "onShowPress");           
		Toast.makeText(this, "onShowPress", Toast.LENGTH_SHORT).show();
	}

	// 用户(轻触触摸屏后)松开,由一个1个MotionEvent ACTION_UP触发

	public   boolean  onSingleTapUp(MotionEvent e) {
		Log.i("MyGesture", "onSingleTapUp");
		Toast.makeText(this, "onSingleTapUp", Toast.LENGTH_SHORT).show();
		return true;
	}

	// 用户按下触摸屏、快速移动后松开,由1个MotionEvent ACTION_DOWN, 多个ACTION_MOVE, 1个ACTION_UP触发        

	public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {    
		Log.i("MyGesture", "onFling");
		Toast.makeText(this, "onFling", Toast.LENGTH_LONG).show();     
		return true;
	}

  	// 用户按下触摸屏,并拖动,由1个MotionEvent ACTION_DOWN, 多个ACTION_MOVE触发

	public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {            
		Log.i("MyGesture", "onScroll");
 		Toast.makeText(this, "onScroll", Toast.LENGTH_LONG).show();
		return true;
 	}

  	// 用户长按触摸屏,由多个MotionEvent ACTION_DOWN触发

	public   void  onLongPress(MotionEvent e) {
		Log.i("MyGesture", "onLongPress");
		Toast.makeText(this, "onLongPress", Toast.LENGTH_LONG).show();
 	}
}

本示例中,用到了OnGestureListener接口的onScroll()和OnFling()方法,涉及到了Android系统坐标及触摸MotionEvent e1和e2、速度velocityX、velocityY等值,那么这里就顺便补充下Android屏幕坐标系如下图:

 

(1)MotionEvent中 e1是手指第一次按上屏幕的起点,e2是抬起手指离开屏幕的终点,根据上图Android屏幕坐标系可知:

手指向右滑动,终点(e2)在起点(e1)的右侧,有e2.getX() - e1.getX() 大于0 手指向左滑动,终点(e2)在起点(e1)的左侧,有e2.getX() - e1.getX() 小于0 手指向下滑动,终点(e2)在起点(e1)的下侧,有e2.getY() - e1.getY() 大于0 手指向上滑动,终点(e2)在起点(e1)的上侧,有e2.getY() - e1.getY() 小于0

(2)onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY)

distanceX,是前后两次call的X距离,不是e2与e1的水平距离 distanceX,是前后两次call的Y距离,不是e2与e1的垂直距离 具体数值的方向,请详见上图(中)

(3)onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY)

velocityX,是X轴的每秒速度 velocityY,是Y轴的每秒速度 具体数值的方向,请详见上图(右) 仔细观察可以发现:velocityX、velocityY的方向与distanceX、distanceY方向正好相反

 


© 著作权归作者所有

共有 人打赏支持
gavin_jin
粉丝 27
博文 126
码字总数 143090
作品 0
海淀
技术主管
私信 提问
android手势操作滑动效果触摸屏事件处理

很多时候,利用触摸屏的Fling、Scroll等Gesture(手势)操作来操作会使得应用程序的用户体验大大提升,比如用Scroll手势在 浏览器中滚屏,用Fling在阅读器中翻页等。在Android系统中,手势的...

Fiter
2011/02/11
0
9
关于Android手势类GestureDetector类

1> 原理: 在Android系统中,每一次手势交互都会依照下列顺序执行 A、接触屏那一刹那,触发一个MotionEvent事件 B、该事件被onTouchListener监听,在onTouch()方法中捕获MotionEvent对象 C、...

ZHXIA
2016/04/21
67
0
编写 Android 触摸屏手势识别程序

很多时候,利用触摸屏的Fling、Scroll等Gesture(手势)操作来操作会使得应用程序的用户体验大大提升,比如用Scroll手势在 浏览器中滚屏,用Fling在阅读器中翻页等。在Android系统中,手势的...

红薯
2009/07/02
36.8K
22
GestureDetector.OnGestureListener 详解

感谢android中国开发者的众多先驱,本文主要内容来自于总结,一小部分是自己的体会。主要参考文章为: http://www.williamhua.com/2009/04/23/android-touchscreen-gesture-recogniton/ htt...

caikezhan
2012/03/31
0
0
android 中手势GestureDetector

android 中手势GestureDetector GestureDetector 的代码使用 好的我们现在来分析一下 这些事件 onDown(MotionEvent motionEvent)------ 当按下屏幕的时候 触发, 触发回调方法 onDown(ACTIO...

乱取名字
2016/12/12
4
0

没有更多内容

加载失败,请刷新页面

加载更多

商品详情页上拉查看详情

商品详情页上拉查看详情 目录介绍 01.该库介绍 02.效果展示 03.如何使用 04.注意要点 05.优化问题 06.部分代码逻辑 07.参考案例 01.该库介绍 模仿淘宝、京东、考拉等商品详情页分页加载的UI效...

潇湘剑雨
16分钟前
0
0
Netty内存池之PoolArena详解

PoolArena是Netty内存池中的一个核心容器,它的主要作用是对创建的一系列的PoolChunk和PoolSubpage进行管理,根据申请的不同内存大小将最终的申请动作委托给这两个子容器进行管理。整体上,P...

爱宝贝丶
21分钟前
0
0
Django使用Channels实现WebSocket--下篇

希望通过对这两篇文章的学习,能够对Channels有更加深入的了解,使用起来得心应手游刃有余 通过上一篇《Django使用Channels实现WebSocket--上篇》的学习应该对Channels的各种概念有了清晰的认...

运维咖啡吧
28分钟前
1
0
linux下设置定时执行shell脚本的示例

很多时候我们有希望服务器定时去运行一个脚本来触发一个操作,比如说定时去备份服务器数据、数据库数据等 不适合人工经常做的一些操作这里简单说下 shell Shell俗称壳,类似于DOS下的command...

阿锋zxf
31分钟前
2
0
介绍Kubernetes监控Heapster

什么是Heapster? Heapster是容器集群监控和性能分析工具,天然的支持Kubernetes和CoreOS,Kubernetes有个出名的监控agent—cAdvisor。在每个kubernetes Node上都会运行cAdvisor,它会收集本机...

xiangyunyan
33分钟前
0
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部