首先,在Android系统中,每一次手势交互都会依照以下顺序执行。

  1. 接触接触屏一刹那,触发一个MotionEvent事件。

  2. 该事件被OnTouchListener监听,在其onTouch()方法里获得该MotionEvent对象。

  3. 通过GestureDetector(手势识别器)转发次MotionEvent对象至OnGestureListener。

  4. OnGestureListener获得该对象,听根据该对象封装的的信息,做出合适的反馈。

这个顺序可以说就是手势交互的原理,下面一同来了解一下MotionEvent、GestureDetector和OnGestureListener。

MotionEvent: 这个类用于封装手势、触摸笔、轨迹球等等的动作事件。其内部封装了两个重要的属性X和Y,这两个属性分别用于记录横轴和纵轴的坐标。

GestureDetector: 识别各种手势。

OnGestureListener: 这是一个手势交互的监听接口,其中提供了多个抽象方法,并根据GestureDetector的手势识别结果调用相对应的方法。

下面我再通过一个切换图片的代码示例,演示一下手势交互的实现,让大伙对上面的执行顺序,以及各手势动作的区分有一个更加深刻的了解和记忆。

首先,提供一个只有ImageView的布局文件——main.xml。

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"> <ImageView android:id="@+id/image"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_gravity="center"/>
</LinearLayout>

然后,完成我们的Activity,因为要监听触摸屏的触摸事件和手势时间,所以该Activity必须实现OnTouchListener和OnGestureListener两个接口,并重写其中的方法。具体代码如下:

package com.example.gesture;import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.GestureDetector;
import android.view.GestureDetector.OnGestureListener;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
import android.widget.ImageView;public class MainActivity extends Activity implements OnTouchListener, OnGestureListener { //创建一个用于识别收拾的GestureDetector对象waiyuwu.blogcn.com private GestureDetector detector = new GestureDetector(this); //定义一个数组,用于放漂亮的女孩 int[] girls = new int[]{R.drawable.a1, R.drawable.a2, R.drawable.a3,R.drawable.a4,R.drawable.a5}; //定义数组下标,以方便观看各个女孩 private int index = 1; private ImageView image; private int alpha = 255;@Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); image = (ImageView)findViewById(R.id.image); //设置一个初始显示的girl吧 image.setImageResource(girls[index]); //监听这个ImageView组件上的触摸屏时间 image.setOnTouchListener(this); //下面两个要记得设哦,不然就没法处理轻触以外的事件了,例如抛掷动作。 image.setLongClickable(true); detector.setIsLongpressEnabled(true); }//用于呼喊下一个女孩的方法 public void goNext(){ index++; //这句话是求余,取int类型的绝对值,这样就能形成一个循环,让图片循环显示index = Math.abs(index % girls.length); image.setImageResource(girls[index]); } //重写OnTouchListener的onTouch方法 //此方法在触摸屏被触摸,即发生触摸事件(接触和抚摸两个事件,挺形象)的时候被调用。 //触摸和移动的过程中不断地被调用@Override public boolean onTouch(View v, MotionEvent event) { Log.v("aa", "此方法在触摸屏被触摸 ");detector.onTouchEvent(event); return true; } //在按下动作时被调用 (只要手指刚碰到屏幕就会被调用 第一个被调用)@Override public boolean onDown(MotionEvent e) { Log.v("aa", "在按下动作时被调用 ");return false; } //在抛掷动作时被调用 @Override public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) { Log.v("aa", "velocityX------|"+velocityX);Log.v("aa", "velocityY------|"+velocityY);if(velocityY > 0){Log.v("aa", "树立方向有速度");}//velocityX表示横向的移动,根据手指移动的方向切换女孩 //手从右向左滑动if(velocityX < 0 &&   Math.abs(velocityY) < Math.abs(velocityX)  ){ goNext(); //手从左向右滑动}else if(velocityX > 0 && Math.abs(velocityY) < Math.abs(velocityX)){ goPrevious(); //手指从上往下滑动}else if(velocityY > 0 && Math.abs(velocityX) < Math.abs(velocityY)){ Log.v("aa", "手指从上往下滑动");alpha-=20;if(alpha < 0){alpha = 0;}image.setAlpha(alpha);//手指从下往上滑动}else if(velocityY < 0 && Math.abs(velocityX) < Math.abs(velocityY)){ Log.v("aa", "手指从下往上滑动");alpha+=20;if( 255 < alpha ){alpha = 255;}image.setAlpha(alpha);} return false; } //用户呼唤上一个女孩的方法 public void goPrevious(){ index--; index = Math.abs(index % girls.length); image.setImageResource(girls[index]); } //在长按时被调用 @Override public void onLongPress(MotionEvent e) { Log.v("aa", "长按图片");} //在滚动时调用 (这个在你手在屏幕上滑动(无论左右移动,)只在移动的过程中不断调用)@Override public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {Log.v("aa", "在滚动时调用  ");return false; } //在按住时被调用 这个长按,短按(轻点都会被调用)@Override public void onShowPress(MotionEvent e) { Log.v("aa", "在按住时被调用 ");} //在抬起时被调用 这个长按(不会被调用),短按(会被调用)@Override public boolean onSingleTapUp(MotionEvent e) { Log.v("aa", "在抬起时被调用  ");return false; }
}

这里面的滑动手机会产生速度(velocityX横向速度,velocityY纵向速度)根据速度的比较,根据速度的绝对值和是否为负值可以分为8个区域,可以为每个区域设置不同的操作,我这里只是做了四个,绿色分割的。看图

1.按下(onDown): 刚刚手指接触到触摸屏的那一刹那,就是触的那 一下。

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

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

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

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

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

任何手势动作都会先执行一次按下(onDown)动作。

7.长按(onLongPress)动作前一定会执行一次按住(onShowPress)动作。

8.按住(onShowPress)动作和按下(onDown)动作之后都会执行一次抬起(onSingleTapUp)动作。

9.长按(onLongPress)、滚动(onScroll)和抛掷(onFling)动作之后都不会执行抬起(onSingleTapUp)动作。

Android的手势识别相关推荐

  1. 简述Android触摸屏手势识别

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

  2. Android Gesture 手势识别使用实例 - Android - mobile - ITeye论坛

    Android Gesture 手势识别使用实例 - Android - mobile - ITeye论坛 主题:Android Gesture 手势识别使用实例 精华帖 (0) :: 良好帖 (0) ...

  3. Android Tip : Android GestureDetector 手势识别 抬起 操作

    [Android Tip] [Android GestureDetector 手势识别 抬起 操作] 关于GestureDetector的用法,大家自行Google 这里只说一个小点:就是手势监听中缺 ...

  4. 我的Android进阶之旅------Android Gusture 手势识别小案例

    Step1: 生成一个Android Gusture Builder程序用于画Gusture然后存储起来用于其它的项目 首先导入  android SDK \android-sdk-windows\s ...

  5. 实现在Android 多点手势识别

    google 提供的API中,有个类,大家都很熟悉,GestureDetector.使用它,我们可以识别用户通常会用的手势.但是,这个类不支持多点触摸(可能 google认为没有人会在几个手指都在屏幕 ...

  6. 理解Android的手势识别

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

  7. Android Gesture 手势识别使用实例

    很高兴能在Android1.6的sdk看到手势识别这一功能,之前一直在想,如何在android中实现nds游戏那样用手势(准确点应该是笔势)来控制游戏角色?现在总算看到一点曙光了,不过手势要做到笔势那 ...

  8. Android 全局手势识别原理

    本文是对全局手势识别进行分析,那什么是全局手势呢?简单来说就是在任何界面都需要识别的手势,比如:在任何界面从手机屏幕左侧滑动,当前的界面会退出 (类似 back 键). 我们知道,在 Android ...

  9. android 手势识别 (缩放 单指滑动 多指滑动)

    Android P 手势识别 1.前提介绍: 2.单指相关 2.双指缩放 3.多指滑动. 4.总体识别代码 1.前提介绍: 关于Android 手势识别就是当前view 根据用户的不同touch行为, ...

最新文章

  1. DETR3D:将DETR用于3D目标检测任务
  2. JUnit学习摘要+入门实例 (junit4)
  3. JS判断IE6/IE7/IE8系列的写法
  4. 【华为云技术分享】十分钟从入门到精通(下)——OBS权限配置
  5. 浅说项目管理中的Action以及3W1P原则
  6. Cacti+Nagios安装后按自己的相关要求修改相关信息
  7. c语言代码re通常什么错误,求帮助 C语言realloc和free触发断点的问题
  8. CLion IDE 来调试 JVM 源码
  9. python项目实战:实现数据可视化三维拟合
  10. SLAM学习------Sophus模板类的安装和使用
  11. 纸牌、挖金子源码链接
  12. LeetCode 101Pro
  13. 【Java】用java程序求李白的酒
  14. wxid 微信号设置隐私 微信号搜不到 恢复好友总结
  15. No ‘Access-Control-Allow-Origin‘ header is present on the requested resource Vue配置代理解决跨域问题
  16. 总结 拦截器(Interceptor) 和 过滤器(Filter)的区别
  17. 如何在Ubuntu上方便使用OpenAI API key
  18. 2023年东南大学英语笔译考研上岸前辈备考经验指导
  19. 透彻分析微信公众平台三大矛盾
  20. 拉拉米抢单发单系统源码+二开ui带视频介绍+ 放量功能

热门文章

  1. 前魅族副总裁李楠上手魅族17:颜值提升了
  2. 嘀嗒公司被约谈 要求全面暂停进出京跨城网约车、顺风车等业务
  3. 地铁人多不多可在线查询了 高德地图率先在北京上线新功能
  4. 爱奇艺推出国际娱乐服务iQIYI App:科技和内容同时出海 携手Astro展开马来西亚地区本土化运营...
  5. 区块链的有趣应用:买彩票、云养鸡、查茅台
  6. 朋友圈终于对利诱打卡行为动手了!多款英语学习类软件中枪
  7. 特斯拉又烧一辆!车库里起火 所幸无人受伤
  8. 苹果禁用FaceTime多人聊天功能:漏洞将很快修复
  9. 人生路上必须明白的七个哲理[转]
  10. Fiddler实现手机抓包