理解Android的手势识别

原文:http://blog.csdn.net/noodies/article/details/6913424

对于触摸屏,其原生的消息无非按下、抬起、移动这几种,我们只需要简单重载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
时间: 2024-09-18 10:20:47

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

理解Android的手势识别提高APP的用户体验_Android

对于触摸屏,其原生的消息无非按下.抬起.移动这几种,我们只需要简单重载onTouch或者设置触摸侦听器setOnTouchListener即可进行处理.不过,为了提高我们的APP的用户体验,有时候我们需要识别用户的手势,Android给我们提供的手势识别工具GestureDetector就可以帮上大忙了. 基础 GestureDetector的工作原理是,当我们接收到用户触摸消息时,将这个消息交给GestureDetector去加工,我们通过设置侦听器获得GestureDetector处理后的手

理解Android的手势识别提高APP的用户体验

对于触摸屏,其原生的消息无非按下.抬起.移动这几种,我们只需要简单重载onTouch或者设置触摸侦听器setOnTouchListener即可进行处理.不过,为了提高我们的APP的用户体验,有时候我们需要识别用户的手势,Android给我们提供的手势识别工具GestureDetector就可以帮上大忙了. 基础 GestureDetector的工作原理是,当我们接收到用户触摸消息时,将这个消息交给GestureDetector去加工,我们通过设置侦听器获得GestureDetector处理后的手

深入理解Android手势识别_Android

对于触摸屏,其原生的消息无非按下.抬起.移动这几种,我们只需要简单重载onTouch或者设置触摸侦听器setOnTouchListener即可进行处理.不过,为了提高我们的APP的用户体验,有时候我们需要识别用户的手势,Android给我们提供的手势识别工具GestureDetector就可以帮上大忙了. 基础 GestureDetector的工作原理是,当我们接收到用户触摸消息时,将这个消息交给GestureDetector去加工,我们通过设置侦听器获得GestureDetector处理后的手

深度理解Android InstantRun原理以及源码分析

深度理解Android InstantRun原理以及源码分析 @Author 莫川 Instant Run官方介绍 简单介绍一下Instant Run,它是Android Studio2.0以后新增的一个运行机制,能够显著减少你第二次及以后的构建和部署时间.简单通俗的解释就是,当你在Android Studio中改了你的代码,Instant Run可以很快的让你看到你修改的效果.而在没有Instant Run之前,你的一个小小的修改,都肯能需要几十秒甚至更长的等待才能看到修改后的效果. 传统的代

深入理解Android之Gradle

深入理解Android之Gradle 格式更加精美的PDF版请到http://vdisk.weibo.com/s/z68f8l0xTYrZt 下载 Gradle是当前非常"劲爆"得构建工具.本篇文章就是专为讲解Gradle而来.介绍Gradle之前先说点题外话. 一.题外话 说实话我在大法工作的时候就见过Gradle.但是当时我一直不知道这是什么东西.而且大法工具组的工程师还将其和Android Studio大法版一起推送偶一看就更没兴趣了.为什么那个时候如此不待见Gradle呢因为我

理解Android虚拟机体系结构(转)

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

如何理解android中的api level

问题描述 如何理解android中的api level 刚开始是api level 1 现在api level 多少了 是不是随着android版本的更新而不断的更新 解决方案 可以查看android api的官网,http://source.android.com/source/build-numbers.html level是会随版本更新的,现在都二十几了,应该是23了吧 解决方案二: http://blog.csdn.net/nihaoqiulinhe/article/details/50

理解Android编译命令

工欲善其事,必先利其器,对于想要深入学习Android源码,必须先掌握Android编译命令. 一.引言 关于Android Build系统,这个话题很早就打算整理下,迟迟没有下笔,决定跟大家分享下.先看下面几条指令,相信编译过Android源码的人都再熟悉不过的. source /opt/android1204_17.conf  source setenv.sh lunch make -j12 记得最初刚接触Android时,同事告诉我用上面的指令就可以编译Android源码,指令虽短但过几天

《Android应用开发攻略》——1.6 理解Android生命周期

1.6 理解Android生命周期 Ian Darwin1.6.1 问题 Android应用没有"主"(main)方法:你必须了解它们如何开始和停止.1.6.2 解决方案 android.Activity类提供许多明确定义的生命周期方法,在应用程序启动.挂起.重新启动等情况下调用,还提供了一个方法,用于将活动标记为完成.1.6.3 讨论 你的Android应用程序运行于自己的UNIX进程中,所以一般来说不会直接影响其他运行中的应用程序.Dalvik VM与操作系统接口,在应用程序启动.