Android为手势检测提供了一个GestureDetector类,GestureDetector实例代表了一个手势检测器,创建GestureDetector时需要传入一个GestureDetector.OnGestureListener实例,GestureDetector.OnGestureListener就是一个监听器。负责对用户的手势行为提供相应。
GestureDetector.OnGestureListener里包含的事件处理方法如下。
》boolean onDown(MotionEvent e):当触碰事件按下时触发该方法。
》boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY):当用户在触摸屏上“拖过”时触发该方法。其中velocityX、velocityY代表“拖过”动作在横向、纵向上的速度。
》abstract void onLongPress(MotionEvent e):当用户在屏幕上长按时触发该方法。
》boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY):当用户在屏幕上“滚动”时触发该方法。
》void onShowPress(MotionEvent e):当用户在触摸屏上按下、而且还未移动和松开时触发该方法。
》boolean onSingleTapUp(MotionEvent e):用户在触摸屏上的轻击事件将会触发该方法。
使用Android的手势检测只需两个步骤。
1.创建一个GestureDetector对象。创建该对象时必须实现一个GestureDetector.OnGestureListener监听器实例。
2.为应用程序的Activity(偶尔也可为特定组件)的TouchEvent事件绑定监听器,在事件处理中指定把Activity(或特定组件)上的TouchEvent事件交给GestureDetector处理。
经过上面两个步骤之后,Activity(或特定组件)上的TouchEvent事件就会交给GestureDetector处理,而GestureDetector就会检测是否触发了特定的手势动作。
下面的程序测试了用户的不同动作到底触发那种手势动作。
package com.example.androidioanddatastore.gesturedetector;
import com.example.androidioanddatastore.R;
import android.app.Activity;
import android.os.Bundle;
import android.view.GestureDetector.OnGestureListener;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.widget.Toast;
/**
* GestureDetector的使用
* @author Administrator
*
*/
public class GestureActivity extends Activity implements OnGestureListener {
/**定义手势监听器实例*/
private GestureDetector mDetector;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_gesture);
//创建手势监听器
mDetector = new GestureDetector(this, this);
}
/**
* 将该activity上的触碰事件交给GestureDetector处理
* */
@Override
public boolean onTouchEvent(MotionEvent event) {
return mDetector.onTouchEvent(event);
}
@Override
public boolean onDown(MotionEvent e) {
Toast.makeText(this, "按下", Toast.LENGTH_SHORT).show();
return false;
}
@Override
public void onShowPress(MotionEvent e) {
Toast.makeText(this, "按下,而且还未移动和松开", Toast.LENGTH_SHORT).show();
}
@Override
public boolean onSingleTapUp(MotionEvent e) {
Toast.makeText(this, "轻击事件", Toast.LENGTH_SHORT).show();
return false;
}
@Override
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX,
float distanceY) {
Toast.makeText(this, "上下滚动", Toast.LENGTH_SHORT).show();
return false;
}
@Override
public void onLongPress(MotionEvent e) {
Toast.makeText(this, "长按时", Toast.LENGTH_SHORT).show();
}
@Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
float velocityY) {
Toast.makeText(this, "左右拖过", Toast.LENGTH_SHORT).show();
return false;
}
}
上面的demo,只是简单地检测到了当用户随意在屏幕上触碰时,到底执行了那些手势。
下面的demo,是通过手势来缩放图片。
demo只是来联系GestureDetector的使用,在手机上面测试,发现每个触摸事件的回调方法会被触发多次,demo中,图片的资源回收会出现问题。。。。
1.activity
package com.example.androidioanddatastore.gesturedetector;
import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Matrix;
import android.graphics.drawable.BitmapDrawable;
import android.os.Bundle;
import android.view.GestureDetector;
import android.view.GestureDetector.OnGestureListener;
import android.view.MotionEvent;
import android.widget.ImageView;
import com.example.androidioanddatastore.R;
/***
* GestureDetector实现图片缩放
* @author Administrator
*
*/
public class GestureZoomActivity extends Activity implements OnGestureListener{
/**定义手势检测器实例*/
private GestureDetector mDetector;
/**缩放组件*/
private ImageView mImageView;
/**初始的图片资源*/
private Bitmap mBitmap;
/**图片的宽高*/
private int width, height;
/**记录当前的缩放比*/
private float currentScale = 1f;
/**控制图片缩放的Matrix对象*/
private Matrix mMatrix;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_gesture_zoom);
//创建手势监听器对象
mDetector = new GestureDetector(this, this);
mImageView = (ImageView) findViewById(R.id.imageview);
mMatrix = new Matrix();
//获取被缩放的源图片
mBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher);
//获取位图的宽高
width = mBitmap.getWidth();
height = mBitmap.getHeight();
//设置ImageView初始化时显示的图片
mImageView.setImageBitmap(BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher));
}
@Override
public boolean onTouchEvent(MotionEvent event) {
//将该activity上面的触碰事件交给GestureDetector处理
return mDetector.onTouchEvent(event);
}
/**
* 左右滑动回调事件
*/
@Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
float velocityY) {
velocityX = velocityX > 4000 ? 4000 : velocityX;
velocityX = velocityX < -4000 ? -4000 : velocityX;
//根据手势速度来计算缩放比,如果velocityX>0,放大图像,否则缩小图片
currentScale += currentScale * velocityX / 4000.0f;
//保证currentScale不等于0
currentScale = currentScale > 0.01 ? currentScale : 0.01f;
//重置Matrix
mMatrix.reset();
//缩放Matrix
mMatrix.setScale(currentScale, currentScale, 160, 200);
BitmapDrawable tmp = (BitmapDrawable) mImageView.getDrawable();
//如果图片还未回收,先强制回收图片
if(tmp.getBitmap().isRecycled()){
tmp.getBitmap().recycle();
}
//根据源位图和Matrix创建新位图
Bitmap bitmap = Bitmap.createBitmap(mBitmap, 0, 0, width, height, mMatrix, true);
//显示新位图
mImageView.setImageBitmap(bitmap);
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
}
}
2.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=".GestureZoomActivity" >
<ImageView
android:id="@+id/imageview"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</RelativeLayout>