android事件系列-onTouch事件与手势操作

提示记忆:应用流程:在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] 纯文本查看 复制代码
?
1
GestureDetector myGesture = new GestureDetector(MainActivity.this,this);

在onTouch方法中调用GestureDetector 的方法

[Java] 纯文本查看 复制代码
?
1
myGesture.onTouchEvent(event);


关于按钮功能的说明:
可以拖动的按钮,这个功能的核心代码是

[Java] 纯文本查看 复制代码
?
1
v.layout(x - temp[0], y - temp[1], x + v.getWidth() - temp[0], y - temp[1] + v.getHeight());


在滑动事件中调用

[Java] 纯文本查看 复制代码
?
1
view.layout(int l, int t, int r, int b)

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值