Android手势检测技术(一)

来源:互联网 发布:淘宝如何加入天猫 编辑:程序博客网 时间:2024/04/30 20:22
    Android为手势检测提供了一个GestureDetector类GestureDetector实例代表了一个手势检测器创建GestureDetector时需要传入一个GestureDetector.OnGestureListener实例,其中GestureDetector.OnGestureListener就是一个监听器,负责对用户的手势行为提供响应。
转载请表明出处:http://blog.csdn.net/u012637501(嵌入式_小J的天空)
一、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

0 0
原创粉丝点击