手势检测(一)

Android为手势检测提供了一个GestureDetector类,GestureDetector实例代表了一个手势检测器,创建GestureDetector时需要传入一个GestureDetector.OnGestureListener实例,其中GestureDetector.OnGestureListener就是一个监听器,负责对用户的手势行为提供响应。

一、API

1.GestureDetector类

(1)功能简介:该类通过使用提供的MotionEvents用于检测各种手势事件,当检测到一个手势事件时会调用GestureDetector.OnGestureListener接口为用户的手势行为提供响应。具体使用如下:

a.为指定视图(View)创建一个GestureDetector实例;

b.实现 onTouchEvent(MotionEvent)方法,将该Activity上的触碰世家交给GestureDetector处理;

(2)继承关系

java.lang.Object

? android.view.GestureDetector

(3)内部类


interface
GestureDetector.OnDoubleTapListener 响应双击屏幕事件

interface
GestureDetector.OnGestureListener 响应手势事件

class
GestureDetector.SimpleOnGestureListener 当仅需要监听所有手势的一个子集时使用

(4)构造方法


GestureDetector(Context context, GestureDetector.OnGestureListener listener)

构造一个GestureDetector实例,传入一个事件监听器对象listener(作为参数)


GestureDetector(Context context, GestureDetector.OnGestureListener listener, Handler handler)

Creates a GestureDetector with the supplied listener that runs deferred events on the thread associated with the supplied Handler

(5)常用方法

boolean isLongpressEnabled() :长按激活

boolean onTouchEvent(MotionEvent
ev) :分析并根据传入的运动事件(MotionEvent ev),调用响应的方法作出响应

void setOnDoubleTapListener(GestureDetector.OnDoubleTapListener
onDoubleTapListener) :设置监听器响应双击或相关手势事件

2.public static interface 

GestureDetector.OnGestureListener接口

(1)功能简介:用于监听所有手势,并作出相应的响应;

(2)手势事件的处理方法

abstract
boolean onDown(MotionEvent e) :当触碰事件按下时触发该方法;

abstract
boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY):当用户在触摸屏上"拖过"时触发该方法。其中velocityX、velosityY代表"拖过"动作在横向、纵向的速度

abstract
void onLongPress(MotionEvent e) :当用户在屏幕长按时触发该方法

abstract
boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) :当用户在屏幕"滚动"时触发该方法

abstract
void onShowPress(MotionEvent e) :当用户在触摸屏上按下,而且还未移动和松开时触发该方法

abstract
boolean onSingleTapUp(MotionEvent e) :用户在触摸屏上的轻击事件将会触发该方法

注意:上述方法中只要有一个为抽象方法,则GestureDetector.OnGestureListener为抽象接口,我们在使用的时候需要实现全部方法。

二、Android手势检测开发思路

1.创建一个GestureDetector对象。创建该对象时必须实现一个GestureDetector.OnGestureListener监听器实例,且作为参数传入。

GestureDetector detector=r=new GestureDetector(this,GestureDetector.OnGestureListener
listener);

2.为应用程序的Activity(或特定组件)的TouchEvent事件绑定事件监听器,在事件处理中指定把Activity(或特定组件)上的TouchEvent事件交给GestureDetector处理,而GestureDetector就会检测是否触发了特定的手势动作并作出相应的响应。

public boolean onTouchEvent(MotionEvent event) {

return detector.onTouchEvent(event);

}

3.实现各种手势事件的响应方法。

三、实战源码

1.实现:测试用户的不同动作,判定触发了哪种手势

/*功能:根据用户的不同动作检测判定触发的是哪种手势动作*/
package com.example.android_gesture_1;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.provider.ContactsContract;
import android.view.GestureDetector;
import android.view.GestureDetector.OnGestureListener;
import android.view.MotionEvent;
import android.widget.Toast;
public class GestureTest extends Activity
 implements OnGestureListener
{
 //1.定义手势检测实例
 GestureDetector detector;
 @Override
 protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.main);
 //2.创建手势检测器:this-表明该Activity本身会作为GestureDetector.OnGestureListener监听器
  detector=new GestureDetector(this,this);
 }
 //3.指定把Activity的TouchEvent交给GestureDetector处理
 @Override
 public boolean onTouchEvent(MotionEvent event) {
  return detector.onTouchEvent(event);
 }
 //4.手势检测判定--------------------------------------------/
 @Override	//a.当触碰事件按下时触发
 public boolean onDown(MotionEvent e) {
//	 Toast.makeText(this, "onDown:当触碰事件按下时触发", Toast.LENGTH_SHORT).show();
  return false;
 }
 @Override	//b.当用户在触摸屏上按下,而且还未移动和松开
 public void onShowPress(MotionEvent e) {
//	 Toast.makeText(this, "onShowPress:当用户在触摸屏上按下,而且还未移动和松开", Toast.LENGTH_SHORT).show();
 }
 @Override	//c.当用户在触摸屏上的轻击事件将会触发该方法
 public boolean onSingleTapUp(MotionEvent e) {
//	 Toast.makeText(this, "onSingleTapUp:当用户在触摸屏上的轻击事件将会触发该方法", Toast.LENGTH_SHORT).show();
  return false;
 }
 @Override	//d.当用户在屏幕上“滚动”时触发该方法
 public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX,
   float distanceY) {
 //	Toast.makeText(this, "onScroll:当用户在屏幕上“滚动”时触发该方法", Toast.LENGTH_SHORT).show();
  return false;
 }
 @Override	//e.当用户在屏幕长按时触发该方法
 public void onLongPress(MotionEvent e) {
  Toast.makeText(this, "onLongPress:当用户在屏幕长按时触发该方法", Toast.LENGTH_SHORT).show();
 }
 @Override	//f.当用户在触摸屏上“拖过”时触发该方法
 public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
   float velocityY) {
  Toast.makeText(this, "onFling:当用户在触摸屏上“拖过”时触发该方法", Toast.LENGTH_SHORT).show();
  Intent intent=new Intent(Intent.ACTION_VIEW, ContactsContract.Contacts.CONTENT_URI);	//启动联系人
  startActivity(intent);
  return false;
 }
}

注释:detector=new GestureDetector(this,this);作用是创建一个GestureDetector对象,创建该对象时传入了this作为参数,表明该Activity本身将会作为GestureDetector.OnGestureListener监听器,所以该Activity实现了该接口,并实现了该接口里的全部方法。

效果演示:

2.实现:通过手势缩放图片

使用一个GestureDetector来检测用户的手势,并根据用户手势在横向的速度缩放图片。当手势从左向右挥动时为放大图片;从右向左挥动时为缩小图片;挥动的速度越快,缩放的比例就越大。

package com.example.android_gesture_2;
import android.app.Activity;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Matrix;
import android.graphics.drawable.BitmapDrawable;
import android.os.Bundle;
import android.provider.ContactsContract;
import android.view.GestureDetector;
import android.view.GestureDetector.OnGestureListener;
import android.view.MotionEvent;
import android.widget.ImageView;
public class GestureZoom extends Activity implements OnGestureListener
{
 //1.定义手势检测器实例
 GestureDetector detector;
 ImageView imageview;
 //2.图片相关资源初始化
 Bitmap bitmap;	 //初始的图片资源
 int width,height;	 //定义图片的宽、高
 float currentScale = 1; //记录当前的缩放比例
 Matrix matrix;	 //控制图片缩放的Matrix对象
 @Override
 protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.mian);
 //3.创建手势检测器
  detector=new GestureDetector(this,this);
  imageview=(ImageView)findViewById(R.id.image);
  matrix = new Matrix();
 //4.获取被缩放的源图片
  bitmap=BitmapFactory.decodeResource(this.getResources(),R.drawable.flower);
  width=bitmap.getWidth();	//获取位图宽
  height=bitmap.getHeight();	//获取位图高
  imageview.setImageBitmap(BitmapFactory.decodeResource(this.getResources(), R.drawable.flower));//设置ImageView初始化时显示的图片
 }
 //5.把Activity的OnTouch事件交给GestureDetector处理
 @Override
 public boolean onTouchEvent(MotionEvent event) {
  return detector.onTouchEvent(event);
 }
 //6.手势判定并响应----------------------------------------------------//
 @Override
 public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
   float velocityY) {
  velocityX=velocityX>4000?4000:velocityX;	//横向上的拖动速度velocityX(放大)
  velocityX=velocityX<-4000?-4000:velocityX;	//横向上的拖动速度velocityX(缩小)
  //a.根据手势的速度来计算缩放比例,如果velocityX>0,放大图像,否者缩小图像
  currentScale +=currentScale*velocityX/4000.0f;
  currentScale=currentScale>0.01?currentScale:0.01f;	 //保证currentScale不会等于0
  matrix.reset();	 //重置Matrix
  matrix.setScale(currentScale, currentScale, 160, 200);	//缩放Matrix
  BitmapDrawable tmp=(BitmapDrawable)imageview.getDrawable();
  if(!tmp.getBitmap().isRecycled())	//如果图片还未收回,先强制收回该图片
  {
   tmp.getBitmap().recycle();
  }
  Bitmap bitmap2=Bitmap.createBitmap(bitmap, 0, 0, width,height,matrix,true);//根据原始图位和Matrix创建新图片
  imageview.setImageBitmap(bitmap2);//显示新的位图
  return true;
 }
 //-----------------------------------------------------------------//
 @Override
 public boolean onDown(MotionEvent e) {
  // TODO Auto-generated method stub
  return false;
 }
 @Override
 public void onShowPress(MotionEvent e) {
  // TODO Auto-generated method stub

 }
 @Override
 public boolean onSingleTapUp(MotionEvent e) {
  // TODO Auto-generated method stub
  return false;
 }
 @Override
 public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX,
   float distanceY) {
  // TODO Auto-generated method stub
  return false;
 }
 @Override
 public void onLongPress(MotionEvent e) {
  // TODO Auto-generated method stub

 }

}

注释1:该程序界面布局只有一个ImageView组件,用来显示图片;

效果演示:

3.实现:通过手势实现图片翻页效果

使用一个ViewFlipper组件,通过ViewFlipper组件可使用动画控制多个组件之间的切换效果,从而实现翻页效果。

(1)界面布局文件\res\layout\main.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="com.example.android_gesture_3.GestureFlip" > 

<!-- 定义ViewFlipper组件 -->
<ViewFlipper
android:id="@+id/flipper"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</RelativeLayout>

(2)GestureFlip.java

package com.example.android_gesture_3;
import android.app.Activity;
import android.os.Bundle;
import android.view.GestureDetector;
import android.view.GestureDetector.OnGestureListener;
import android.view.MotionEvent;
import android.view.View;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.ImageView;
import android.widget.ViewFlipper;
public class GestureFlip extends Activity implements OnGestureListener {
 //1.定义ViewFlipper、手势检测、动画数组实例
 ViewFlipper flipper;
 GestureDetector detector;
 Animation[] animations=new Animation[4];	//定义一个动画数组,用于为ViewFlipper指定切换动画效果
 final int FLIP_DISTANCE=50;	 //定义手势动作两点之间的最小距离
 @Override
 protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.main);
 //2.创建手势检测器
  detector=new GestureDetector(this,this);
 //3.ViewFlipper、Animation初始化
  flipper=(ViewFlipper)findViewById(R.id.flipper);	//获取ViewFlipper组件
  flipper.addView(addImageView(R.drawable.photo1)); //为ViewFlipper添加5个ImageView组件
  flipper.addView(addImageView(R.drawable.photo2));
  flipper.addView(addImageView(R.drawable.photo3));
  flipper.addView(addImageView(R.drawable.photo4));
  flipper.addView(addImageView(R.drawable.photo5));
  animations[0] = AnimationUtils.loadAnimation(this,R.anim.abc_slide_out_top);//初始化Animation数组
  animations[1] = AnimationUtils.loadAnimation(this,R.anim.abc_slide_in_top);
  animations[2] = AnimationUtils.loadAnimation(this,R.anim.abc_slide_out_bottom);
  animations[3] = AnimationUtils.loadAnimation(this,R.anim.abc_slide_in_bottom);
  }
 //4.定义添加ImageView的工具方法
 private View addImageView(int resId) {
  ImageView imageView = new ImageView(this);
  imageView.setImageResource(resId);
  imageView.setScaleType(ImageView.ScaleType.CENTER);
  return imageView;
 }
 //5.将该Activity上的触碰事件交给GestureDetector处理
 @Override
 public boolean onTouchEvent(MotionEvent event) {
  return detector.onTouchEvent(event);
 }
 //6.在触摸屏上“拖过”时触发该方法
 @Override
 public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
   float velocityY) {
  //如果第一个触点事件的X坐标大于第二触发事件的X坐标超过FLIP_DISTANCE
  //也就是手势从右向左滑
  if(e1.getX()-e2.getX()>FLIP_DISTANCE)
  {
   //为flipper设置切换的动画效果
   flipper.setAnimation(animations[0]);
   flipper.setAnimation(animations[1]);
   flipper.showPrevious();
   return true;
  }
  //如果第二个触点事件的X坐标大于第一个触点事件的X坐标超过FLIP_DISTANCE
  else if(e2.getX()-e1.getX()>FLIP_DISTANCE)
  {
   //为flipper设置切换的动画效果
   flipper.setAnimation(animations[2]);
   flipper.setAnimation(animations[3]);
   flipper.showPrevious();
   return true;
  }
  return false;
 }
 //-------------------------------------------------------------------------//
 @Override
 public boolean onDown(MotionEvent e) {
   return false;
 }
 @Override
 public void onLongPress(MotionEvent e) {
  // TODO Auto-generated method stub

 }
 @Override
 public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX,
   float distanceY) {
  // TODO Auto-generated method stub
  return false;
 }
 @Override
 public void onShowPress(MotionEvent e) {
  // TODO Auto-generated method stub

 }
 @Override
 public boolean onSingleTapUp(MotionEvent e) {
  // TODO Auto-generated method stub
  return false;
 }
}

注释1:ViewFlipper类

? android.widget.FrameLayout

? android.widget.ViewAnimator

? android.widget.ViewFlipper

一个非常简单的视图动画类,其作用是使添加至该对象的两个或者更多视图显示动画效果,并且每次View只能显示一个视图。当属性android:autoStart设置为"ture"时,将以某个时间间隙自动动态切换ViewFlipper对象中的视图,属性android:flipInterval设置自动切换间隔时间。

void setFlipInterval(int milliseconds):设置切换间隔时间(毫秒)

void startFlipping():通过子视图启动一个计时器周期

void addView(View child, int index, ViewGroup.LayoutParams params) :添加一个子视图到ViewFlipper中

void setInAnimation(Animation inAnimation) :Specifies
the animation used to animate a View that enters the screen.

void setOutAnimation(Animation outAnimation) :Specifies
the animation used to animate a View that exit the screen.

void showNext() :手动显示下一个子视图

void showPrevious():手动显示上一个子视图

注释2:Animation,一个抽象动作的集合

java.lang.Object

? android.view.animation.Animation

注释3:AnimationUtils类

java.lang.Object

? android.view.animation.AnimationUtils

定义了使用动画常见的实用程序

static Animation  loadAnimation(Context context, int id) :从资源中加载一个Animation 对象,其中id为要加载的动作id(如R.anim.abc_slide_out_top)

效果演示:

参考:http://wear.techbrood.com/reference/android/view/GestureDetector.html

时间: 2024-10-22 02:27:28

手势检测(一)的相关文章

Chromium网页输入事件捕捉和手势检测过程分析

连续的输入事件可能会产生一定的手势操作,例如滑动手势和捏合手势.在Chromium中,网页的输入事件是在Browser进程中捕捉的.Browser进程捕获输入事件之后,会进行手势操作检测.检测出来的手势操作将会发送给Render进程处理,因为它们需要应用在网页之上.与此同时,Browser进程也会将原始的输入事件发送给Render进程处理.本文接下来就分析Browser进程处理网页输入事件的过程. 老罗的新浪微博:http://weibo.com/shengyangluo,欢迎关注! 接下来我们

Android 手势检测实战 打造支持缩放平移的图片预览效果(下)

转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/39480503,本文出自:[张鸿洋的博客] 上一篇已经带大家实现了自由的放大缩小图片,简单介绍了下Matrix:具体请参考:Android 手势检测实战 打造支持缩放平移的图片预览效果(上):本篇继续完善我们的ImageView~~ 首先加入放大后的移动~~ 1.自由的进行移动 我们在onTouchEvent里面,加上移动的代码,当然了,必须长或宽大于屏幕才可以移动~~~ @Ov

HTML5 手势检测原理和实现

前言 随着 Hybrid 应用的丰富,HTML5 工程师们已经不满足于把桌面端体验简单移植到移动端,他们觊觎移动原生应用人性化的操作体验,特别是原生应用与生俱来的丰富的手势系统.HTML5 没有提供开箱即用的手势系统,但是提供了更底层一些的对 touch 事件的监听.基于此,我们可以做出自己的手势库. 手势 常用的 HTML5 手势可以分为两类,单点手势和两点手势.单点手势有 tap(单击),double tap(双击),long tap(长按),swipe(挥),move(移动).两点手势有

GestureDetector封装手势检测上下滑动

项目中需要检测ListView的上滑下滑隐藏顶部View控件,之前在网上也有很多实现案例.在git上发现个封装很不错的例子,记录下来. GestureDetector是一个手势检测类,内部有个SimpleOnGestureListener手势监听类. 定义一个抽象类SimpleDetector,继承GestureDetector.SimpleOnGestureListener抽象类,实现View.OnTouchListener接口.这样做有什么好处呢?首先ListView只要setOnTouch

9.3、Libgdx手势检测

(官网:www.libgdx.cn) 触摸屏在输入的基础上增加了手势检测,比如两个手指实现缩放,单击或双击屏幕,长按屏幕等. Libgdx提供了GestureDetector来帮助你检测以下手势: touchDown:用户触摸屏幕. longPress:用户长按屏幕. tap:用户点击屏幕.手指必须在点击初始化的位置不能移动太大. pan:用户滑动手指穿过屏幕. panStop:当pan结束时调用. fling:用户滑动手指穿过屏幕,然后释放.通常是用于滑动检测. zoom:用户使用两个手指移动

OpenCV for iOS 3 及 玩转EV3 之: 在iPhone上做手势检测 并控制EV3 机器人

1 前言 去年我做了一段时间iPhone和LEGO EV3 机器人的研究,当时已经开发了iOS的EV3 wifi版SDK,能够使得iOS与EV3进行互动,但这还远远达不到我曾经设想的效果,且看我之前的博文: [iOS与EV3混合机器人编程系列之一]iOS要干嘛?EV3可以更酷! http://blog.csdn.net/songrotek/article/details/37652771 iPhone不仅仅要作为EV3 的大脑,还要是EV3的眼睛,脸,还有姿态感觉(陀螺仪).因此,我之后转向视觉

翻译:使用红外传感器与Arduino进行简单动作与手势检测

译注:昨天看 Adruino 的 Twitter 推了这篇项目,第一眼就觉得非常有趣,翻译给大家看看.文中的红外传感器比较高级,和淘宝上5块钱的那种只能输出0和1的不一样, TPA81 是可以输出温度的,还是8个连续点. MLX90614 可以输出一点的温度,还卖将近三十,可以想象 TPA81 的价格--而且淘宝上并没有卖 TPA81 的,可见国内还没有仿的.文章也给出了另一个解决方案,使用8个 HC-SR505 来替代,这就便宜了很多.我想了一下,如果要只是实现像文章那样的增减手势,3个 HC

第一章:多点触摸与手势检测

一.响应者链 只要继承了UIResponder的对象就可作为事件的响应者,实际上UIControl继承了UIView,UIView又继承了UIResponder,由此可见,所有的对象都可作为事件的响应者. 当用户与某个控件交互时,该控件将作为"第一响应者(First Responder)",第一响应者将作为响应者链的开始,该事件首先被发送给第一响应者(也就是用户触摸屏幕的控件).事件将沿着响应者链一直向下传播,直到被某个响应者处理.事件响应者链的典型传播路线如下: First Resp

Swift - 各种手势检测大全(UIGestureRecognizer及其子类)

UIGestureRecognizer有许多子类,用于监听一些常见的手势事件,这些子类主要有: 1,UISwipeGestureRecognizer:滑动(快速移动) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 class ViewController: UIViewController {          override func viewDidLoad() {         super.viewDidLoad()