博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
android事件系列-onTouch事件与手势操作
阅读量:6686 次
发布时间:2019-06-25

本文共 4978 字,大约阅读时间需要 16 分钟。

提示记忆:应用流程:在Activity中对控件执行 view.setOnTouchListener( OnTouchListener i);实现里面的OnTouchListener 接口中的方法,重点再于理解里面的方法的实现步骤,
 
触摸,手势操作已经很好的融入了我们的生活。那么
Android
开发中触摸事件要如何捕捉?如何处理?如何识别手势?事件的传递机制又是怎么样的?下面我们将通过一个小例子来进行这方面的学习。
先看效果图
<ignore_js_op>

 

如上图所示,就是一个跟随手指移动的按钮。用来演示我们接下来要说的
onTouch
事件和手势操作。
 
为了让大家看懂里面的代码,我们来先介绍一下基础知识。

onTouch事件

做什么都好先了解原理以后的工作就会更简单,关于手势以及我们熟悉的
onclick
onLongClick
事件都是基于对
onTouch
事件的捕捉和处理。那么在使用手势工具类的前提下我们应该去学习了解基本的
onTouch
事件。

 

onTouch
常用的以下
4
个事件:

1ACTION_DOWN
表示按下了屏幕,第一个执行也是必然执行的方法。

2ACTION_MOVE
表示为移动手势,会不断的执行直到触摸停止。

 

3ACTION_UP 
表示为离开屏幕,触摸停止的时候执行。

 

4ACTION_CANCEL
表示取消手势,不会由用户产生,而是由程序产生的。
一个
Action_DOWN, 
多个
ACTION_MOVE, 1
ACTION_UP
,就构成了
Android
中众多的事件。

onTouch的参数

View
受到
Touch
事件的
view
对象

MotionEvent
包含的事件的详细信息,例如触摸点的信息,触摸事件类型的信息等
MotionEvent
的方法例如
getRowX
所描述的都是触摸点的信息。

几个重要方法的说明:

getRowX
:触摸点相对于屏幕的坐标
getX
: 触摸点相对于
view
的坐标
getTop
: 按钮左上角相对于父
view
LinerLayout
)的
y
坐标
getLeft
: 按钮左上角相对于父
view
LinerLayout
)的
x
坐标

onTouch的返回值

这个部分涉及到事件传递和处理机制,详细的不在此介绍。

 

作用:
这里的返回值代表的是,对于这个触摸事件
touch
是否已经处理完成。
如果我们设置返回值为
true
代表的是处理完成,这样就不会再传递给下一个对象。也就是说后面的控件或者对象就不会接收到触摸事件了。
反之,后面的对象或控件会在此接收到这个触摸事件并被调用。

实践

在学习基础知识之后,我们来看看如何使用这些来实现一个可以拖动的按钮吧。

 

思路

 

这里的主要思路就是在
ACTION_DOWN
按下的第一时间记录下初始的状态,在
ACTION_MOVE
滑动事件中不断的刷新按钮的位置。
为了保证有我们正常理解下的点击事件发生,下面我还加了位置是否移动的判断。

 

下面是实现该功能的内部类
class MyOnTouch implements OnTouchListener{ int[] temp = new int[] { 0, 0 }; Boolean ismove = false; int downX = 0; int downY = 0;    @Override public boolean onTouch(View v, MotionEvent event) { int eventaction = event.getAction();    int x = (int) event.getRawX(); int y = (int) event.getRawY();    switch (eventaction) {    case MotionEvent.ACTION_DOWN: // touch down so check if the temp[0] = (int) event.getX(); temp[1] = y - v.getTop(); downX = (int) event.getRawX(); downY = (int) event.getRawY(); ismove = false; break;    case MotionEvent.ACTION_MOVE: // touch drag with the ball v.layout(x - temp[0], y - temp[1], x + v.getWidth() - temp[0], y - temp[1] + v.getHeight());     if (Math.abs(downX - x) > 10 || Math.abs(downY - y) > 10) ismove = true; break; case MotionEvent.ACTION_UP: if (!ismove) Toast.makeText(MainActivity.this, "你点击了这个按钮", Toast.LENGTH_LONG).show(); break; } return false; } }

然后在给按钮初始化的时候设置这个事件

touchButton.setOnTouchListener(new MyOnTouch());

手势操作

关于手势操作,这里其实说的是
Android
提供的工具类,通过
GestureDetector 
类来识别和处理
onTouch
事件,简化使用。

 

一般用到下面的三个类。

android.view.GestureDetector
手势操作的识别类,通过他来使用下面的识别接口。

android.view.GestureDetector.SimpleOnGestureListener
手势识别的接口类,使用他可以按需重载自己想要的方法,方法多

 

android.view.GestureDetector.OnGestureListener;
手势识别的类,
SimpleOnGestureListener
接口的父类。使用他需要实现他所有的方法。

方法说明:

OnGestureListener有下面的几个方法:

 

按下(
onDown
):
在按下时调用。

抛掷(
onFling
):
手指在触摸屏上迅速移动,并松开的动作。

 

长按(
onLongPress
):
手指按在持续一段时间,并且没有松开。

 

滚动(
onScroll
):
手指在触摸屏上滑动。

 

按住(
onShowPress
):
手指按在触摸屏上,它的时间范围在按下起效,在长按之前。

抬起(
onSingleTapUp
):
手指离开触摸屏的那一刹那。

 

SimpleOnGestureListenerOnGestureListener多出来的方法:
 
双击(
onDoubleTap
双击的第二下
Touch down
时触发

 

双击事件(
onDoubleTapEvent
双击的第二下
Touch down
up
都会触发一次,可用
e.getAction()
区分。

实践

好了,学习完了基础知识之后我们来用手势操作的工具类来实现我们的小按钮吧。

 

下面来实现我们的手势操作内部类。这里我直接实现了
OnGestureListener 
接口,为了更好的演示效果。
class MyGesture implements OnTouchListener, OnGestureListener {    GestureDetector myGesture = new GestureDetector(MainActivity.this,this); View view = null; int[] temp = new int[] { 0, 0 };  @Override public boolean onTouch(View v, MotionEvent event) { //这一步只是我的强迫症而已,因为onTouch事件是不断被调用的 if(view == null) view = v; myGesture.onTouchEvent(event); return false; }  //在按下时调用  @Override public boolean onDown(MotionEvent e) {  temp[0] = (int) e.getX(); temp[1] = ((int) e.getRawY()) - view.getTop(); return false; }  //手指在触摸屏上迅速移动,并松开的动作。 @Override public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {  return false; }  //长按的时候调用 @Override public void onLongPress(MotionEvent e) {   }  //按住然后滑动时调用 @Override public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) { int x = (int) e2.getRawX(); int y = (int) e2.getRawY(); view.layout(x - temp[0], y - temp[1], x + view.getWidth() - temp[0], y - temp[1] + view.getHeight()); return false; }  // 用户轻触触摸屏,尚未松开或拖动,由一个1个MotionEvent ACTION_DOWN触发  // 注意和onDown()的区别,强调的是没有松开或者拖动的状态 @Override public void onShowPress(MotionEvent e) {   }  // 用户(轻触触摸屏后)松开,由一个1个MotionEvent ACTION_UP触发 @Override public boolean onSingleTapUp(MotionEvent e) { Toast.makeText(MainActivity.this, "你点击了按钮", Toast.LENGTH_LONG).show(); return false; }  }

然后在使用的时候给我们的按钮设置进去就好了

touchButton.setOnTouchListener(new MyGesture());

在内部类的开头初始化我们的GestureDetector 处理类

GestureDetector myGesture = new GestureDetector(MainActivity.this,this);
[Java] 纯文本查看 复制代码?1GestureDetector myGesture = new GestureDetector(MainActivity.this,this);在onTouch方法中调用GestureDetector 的方法[Java] 纯文本查看 复制代码?1myGesture.onTouchEvent(event);关于按钮功能的说明:可以拖动的按钮,这个功能的核心代码是[Java] 纯文本查看 复制代码?1v.layout(x - temp[0], y - temp[1], x + v.getWidth() - temp[0], y - temp[1] + v.getHeight());在滑动事件中调用[Java] 纯文本查看 复制代码?1view.layout(int l, int t, int r, int b)

 

转载地址:http://jfhao.baihongyu.com/

你可能感兴趣的文章
浅拷贝深拷贝Python对象的拷贝
查看>>
hammer.js – 多点触摸手势库
查看>>
android源码开源组合 xbmc + navi-x 看视频不错 免费
查看>>
Hadoop1.2.0开发笔记(八)
查看>>
C#中的ashx文件,用到Session,但是总无法获取Session,经过调试,出现的错误的原因:...
查看>>
NDK-gdb的错误ERROR: Could not extract package's data directory...的解决方法
查看>>
C语言位操作--判断两整数是否异号
查看>>
vCenter Single Sign On 5.1 best practices
查看>>
tomcat的集群配置
查看>>
Reactive Extensions(Rx) 学习
查看>>
SystemTap知识(一)
查看>>
OracleLinux上安装数据库(DBCA)
查看>>
IOS开发 应用程序图标数字角标
查看>>
利用 FormData 对象发送 Key/Value 对的异步请求
查看>>
vlc做转发的命令
查看>>
MySQL:日期函数、时间函数总结
查看>>
【技术贴】三星Note8 N5100实用教程,关闭相机快门声,增加浏览器退出按钮。...
查看>>
C# 调试程序时如何输入命令行参数
查看>>
如何成为强大的程序员?
查看>>
C#获取全部目录和文件
查看>>