理解Android的手势识别

对于触摸屏,其原生的消息无非按下、抬起、移动这几种,我们只需要简单重载onTouch或者设置触摸侦听器setOnTouchListener即可进行处理。不过,为了提高我们的APP的用户体验,有时候我们需要识别用户的手势,Android给我们提供的手势识别工具GestureDetector就可以帮上大忙了。

基础

GestureDetector的工作原理是,当我们接收到用户触摸消息时,将这个消息交给GestureDetector去加工,我们通过设置侦听器获得GestureDetector处理后的手势。

GestureDetector提供了两个侦听器接口,OnGestureListener处理单击类消息,OnDoubleTapListener处理双击类消息。

OnGestureListener的接口有这几个:

// 单击,触摸屏按下时立刻触发

abstract boolean onDown(MotionEvent e);

// 抬起,手指离开触摸屏时触发(长按、滚动、滑动时,不会触发这个手势)

abstract boolean onSingleTapUp(MotionEvent e);

// 短按,触摸屏按下后片刻后抬起,会触发这个手势,如果迅速抬起则不会

abstract void onShowPress(MotionEvent e);

// 长按,触摸屏按下后既不抬起也不移动,过一段时间后触发

abstract void onLongPress(MotionEvent e);

// 滚动,触摸屏按下后移动

abstract boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY);

// 滑动,触摸屏按下后快速移动并抬起,会先触发滚动手势,跟着触发一个滑动手势

abstract boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY);

OnDoubleTapListener的接口有这几个:

// 双击,手指在触摸屏上迅速点击第二下时触发

abstract boolean onDoubleTap(MotionEvent e);

// 双击的按下跟抬起各触发一次

abstract boolean onDoubleTapEvent(MotionEvent e);

// 单击确认,即很快的按下并抬起,但并不连续点击第二下

abstract boolean onSingleTapConfirmed(MotionEvent e);

有时候我们并不需要处理上面所有手势,方便起见,Android提供了另外一个类SimpleOnGestureListener实现了如上接口,我们只需要继承SimpleOnGestureListener然后重载感兴趣的手势即可。

应用

STEP 1: 创建手势侦听对象

package noodies.blog.csdn.net;

import android.content.Context;

import android.view.MotionEvent;

import android.view.GestureDetector.SimpleOnGestureListener;

import android.widget.Toast;

public class MyGestureListener extends SimpleOnGestureListener {

private Context mContext;

MyGestureListener(Context context) {

mContext = context;

}

@Override

public boolean onDown(MotionEvent e) {

Toast.makeText(mContext, "DOWN " + e.getAction(), Toast.LENGTH_SHORT).show();

return false;

}

@Override

public void onShowPress(MotionEvent e) {

Toast.makeText(mContext, "SHOW " + e.getAction(), Toast.LENGTH_SHORT).show();

}

@Override

public boolean onSingleTapUp(MotionEvent e) {

Toast.makeText(mContext, "SINGLE UP " + e.getAction(), Toast.LENGTH_SHORT).show();

return false;

}

@Override

public boolean onScroll(MotionEvent e1, MotionEvent e2,

float distanceX, float distanceY) {

Toast.makeText(mContext, "SCROLL " + e2.getAction(), Toast.LENGTH_SHORT).show();

return false;

}

@Override

public void onLongPress(MotionEvent e) {

Toast.makeText(mContext, "LONG " + e.getAction(), Toast.LENGTH_SHORT).show();

}

@Override

public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,

float velocityY) {

Toast.makeText(mContext, "FLING " + e2.getAction(), Toast.LENGTH_SHORT).show();

return false;

}

@Override

public boolean onDoubleTap(MotionEvent e) {

Toast.makeText(mContext, "DOUBLE " + e.getAction(), Toast.LENGTH_SHORT).show();

return false;

}

@Override

public boolean onDoubleTapEvent(MotionEvent e) {

Toast.makeText(mContext, "DOUBLE EVENT " + e.getAction(), Toast.LENGTH_SHORT).show();

return false;

}

@Override

public boolean onSingleTapConfirmed(MotionEvent e) {

Toast.makeText(mContext, "SINGLE CONF " + e.getAction(), Toast.LENGTH_SHORT).show();

return false;

}

}

STEP 2: 设置手势识别

我们可以在Activity里设置手势识别:

package noodies.blog.csdn.net;

import android.app.Activity;

import android.os.Bundle;

import android.view.GestureDetector;

import android.view.MotionEvent;

public class GestureTestActivity extends Activity {

private GestureDetector mGestureDetector;

@Override

public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.main);

mGestureDetector = new GestureDetector(this, new MyGestureListener(this));

}

@Override

public boolean onTouchEvent(MotionEvent event) {

return mGestureDetector.onTouchEvent(event);

}

}

也可以在自定义的View里面设置手势识别:

package noodies.blog.csdn.net;

import android.content.Context;

import android.util.AttributeSet;

import android.view.GestureDetector;

import android.view.MotionEvent;

import android.view.View;

public class MyView extends View {

private GestureDetector mGestureDetector;

public MyView(Context context, AttributeSet attrs) {

super(context, attrs);

mGestureDetector = new GestureDetector(context, new MyGestureListener(context));

setLongClickable(true);

this.setOnTouchListener(new OnTouchListener() {

public boolean onTouch(View v, MotionEvent event) {

return mGestureDetector.onTouchEvent(event);

}

});

}

}

陷阱

对于自定义View,使用手势识别有两处陷阱可能会浪费你的不少时间。

1:View必须设置longClickable为true,否则手势识别无法正确工作,只会返回Down, Show, Long三种手势

2:必须在View的onTouchListener中调用手势识别,而不能像Activity一样重载onTouchEvent,否则同样手势识别无法正确工作

测试结果

下面是各种操作返回的手势序列,数值0表示触摸屏按下,1表示抬起

单击:down 0, single up 1, single conf 0

短按:down 0, show 0, single up 1

长按:down 0, show 0, long 0

双击:down 0, single up 1, double 0, double event 0, down 0, double event 1

滚动:down 0, (show 0), scrool 2...

滑动:down 0, (show 0), scrool 2..., fling 1

理解Android的手势识别,布布扣,bubuko.com

时间: 2024-08-01 19:11:30

理解Android的手势识别的相关文章

理解Android虚拟机体系结构

1 什么是Dalvik虚拟机 Dalvik是Google公司自己设计用于Android平台的Java虚拟机,它是Android平台的重要组成部分,支持dex格式(Dalvik Executable)的Java应用程序的运行.dex格式是专门为Dalvik设计的一种压缩格式,适合内存和处理器速度有限的系统.Google对其进行了特定的优化,使得Dalvik具有高效.简洁.节省资源的特点.从Android系统架构图知,Dalvik虚拟机运行在Android的运行时库层. 2 Dalvik虚拟机的功能

[活动已结束]《深入理解Android:Wi-Fi、NFC和GPS卷》CSDN社区活动

今天有一个CSDN社区活动,解答关于Android系统的学习.认识.开发等方面的问题,并就<深入理解Android:Wi-Fi.NFC和GPS卷>一书为大家答疑解惑,了解Android Framework的实现原理.活动链接:http://bbs.csdn.net/topics/390765275?page=1#post-397228045 此次活动已经完结,谢谢各位的支持.获奖的三位兄弟是: 以下欢迎大家踊跃提问,在本帖回复就可以,參与活动并提出问题就可以获得100可用分.在大家的积极參与下

《深入理解Android 卷III》第六章 深入理解控件(ViewRoot)系统

<深入理解Android 卷III>即将公布,作者是张大伟.此书填补了深入理解Android Framework卷中的一个主要空白,即Android Framework中和UI相关的部分. 在一个特别讲究颜值的时代,本书分析了Android 4.2中WindowManagerService.ViewRoot.Input系统.StatusBar.Wallpaper等重要"颜值绘制/处理"模块 第6章 深入理解控件(ViewRoot)系统(节选) 本章主要内容: ·  介绍创建

Android菜单详解(一)——理解android中的Menu

前言 今天看了pro android 3中menu这一章,对Android的整个menu体系有了进一步的了解,故整理下笔记与大家分享. PS:强烈推荐<Pro Android 3>,是我至今为止看到的最好的一本android书,中文版出到<精通Android 2>. 理解Android的菜单 菜单是许多应用程序不可或缺的一部分,Android中更是如此,所有搭载Android系统的手机甚至都要有一个"Menu"键,由此可见菜单在Android程序中的特殊性.An

《深入理解Android 卷III》第五章 深入理解Android输入系统

<深入理解Android 卷III>即将公布.作者是张大伟.此书填补了深入理解Android Framework卷中的一个主要空白.即Android Framework中和UI相关的部分.在一个特别讲究颜值的时代,本书分析了Android 4.2中WindowManagerService.ViewRoot.Input系统.StatusBar.Wallpaper等重要"颜值绘制/处理"模块 第5章 深入理解Android输入系统(节选) 本章主要内容: ·  研究输入事件从设

深入理解Android之AOP

深入理解Android之AOP 格式更加精美的PDF版请到:http://vdisk.weibo.com/s/z68f8l0xTgCLK 下载 一.闲谈AOP 大家都知道OOP,即ObjectOriented Programming,面向对象编程.而本文要介绍的是AOP.AOP是Aspect Oriented Programming的缩写,中译文为面向切向编程.OOP和AOP是什么关系呢?首先: l OOP和AOP都是方法论.我记得在刚学习C++的时候,最难学的并不是C++的语法,而是C++所代

《深入理解Android内核设计思想》已陆续在全国各大书店及网上书店上市,感谢大家一直以来的支持~~

今天星期六了,不知道兄弟姐妹们有没有休息,妮子还在上班,努力着上班.最近总是给大家分享点技术有关的文章!好久没静下心和大家聊聊天.继续第三篇,谈SEOer论行业心态!我们每时每刻都在学习,百度也在每时每刻在更新算法.之前做的可能是对的,但现在不一定会对,为什么.之前觉得发外链就有排名,但现在发外链也不一定有排名.因为百度把我们之前认知的都给否定了.对今天谈谈如何否定曾经一些错误认识. 否定心态 在学习的路上,如何去分辨那些才是对的,那些是好的.这些都是客观性认为,在客观性中否定.妮子现在写的文章

[深入理解Android卷一全文-第八章]深入理解Surface系统

由于<深入理解Android 卷一>和<深入理解Android卷二>不再出版.而知识的传播不应该由于纸质媒介的问题而中断,所以我将在CSDN博客中全文转发这两本书的全部内容. 第8章  深入理解Surface系统 本章主要内容 ·  具体分析一个Activity的显示过程. ·  具体分析Surface. ·  具体分析SurfaceFlinger. 本章涉及的源代码文件名称及位置: · ActivityThread.java framework/base/core/java/an

Android开发之深入理解Android 7.0系统权限更改相关文档

摘要: Android 6.0之后的版本增加了运行时权限,应用程序在执行每个需要系统权限的功能时,需要添加权限请求代码(默认权限禁止),否则应用程序无法响应:Android 7.0在Android 6.0的基础上,对系统权限进一步更改,这次的权限更改包括三个方面: APP应用程序的私有文件不再向使用者放宽 Intent组件传递file://URI的方式可能给接收器留下无法访问的路径,触发FileUriExposedException异常,推荐使用FileProvider DownloadMana