android手势框架,安卓的手势识别框架

android2.2开始安卓中出现了ScaleGestureDetector 。从此第一台多点触控的安卓手机出现了,不管是手机还是ScaleGestureDetector都非常了不起。但我疑惑不解的是,为什么ScaleGestureDetector是唯一一个多点触控手势识别api,为什么没有类似于旋转手势识别的api,识别两个手指(或者多个手指)配合而造成的旋转。难道是因为安卓和google之间的专利战争导致的吗?我不管那么多,反正我就是要用,因此我写了这个小项目,用于扩展原有的api,这篇文章将会讲解如何在app中使用这个项目。

为什么我要写这个小框架当我用google搜索实现两个手指旋转的坚决方案的时候,我找到了很多解决此问题的办法,这些办法来自于不同的开发者,但是它们都有一个缺点,就是少了点

如何使用安卓自带的ScaleGestureDetector从如何在activity中使用ScaleGestureDetector开始讲吧

基本代码结构在activity中你需要实现android.view.View.OnTouchListener以及其onTouch(...)方法,这样安卓系统就会在android.view.MotionEvent发生的时候通知它。

public class TouchActivity extends Activity implements OnTouchListener {

public void onCreate(Bundle savedInstanceState) {

// Init stuff here

...

}

public boolean onTouch(View v, MotionEvent event) {

// Handle touch events here

...

}

...

}

现在你可以通过onTouch(...)来获得所有的多点触控事件了,但是相信我,你绝对会写出一堆杂乱无章的代码来,所以还是用android.view.ScaleGestureDetector来优雅的解决这个问题吧。

public class TouchActivity extends Activity implements OnTouchListener {

private ScaleGestureDetector mScaleDetector;

public void onCreate(Bundle savedInstanceState) {

mScaleDetector = new ScaleGestureDetector(getApplicationContext(), new ScaleListener());

...

}

public boolean onTouch(View v, MotionEvent event) {

mScaleDetector.onTouchEvent(event);

}

...

}

首先当然是创建ScaleGestureDetecto 的对象,在这里这个对象是mScaleDetector ,我们将MotionEvent 转交给mScaleDetector.onTouchEvent(event),这样mScaleDetector 就能计算出是否发生了缩放事件。但是我们如何处理用户缩放操作的呢?

使用Listener来处理事件你可能注意到了在初始化ScaleGestureDetector的时候也新建了一个ScaleListener。这个Listener将在scale事件发生的时候通知我们,并传递相关的数据。ScaleListener是我们定义的一个内部类:

public class TouchActivity extends Activity implements OnTouchListener

...

private class ScaleListener extends ScaleGestureDetector.SimpleOnScaleGestureListener {

@Override

public boolean onScale(ScaleGestureDetector detector) {

mScaleSpan = detector.getCurrentSpan(); // average distance between fingers

return true;

}

}

}

ScaleListener实现了ScaleGestureDetector的内部接口SimpleOnScaleGestureListener。这样ScaleGestureDetector就知道如何在scale事件发生的时候去调用我们的这个实现。在onScale(...)方法中,我们可以读取出需要的来自ScaleGestureDetector的数据。

使用scale的相关数据既然ScaleListener是一个内部类,因此我们可以使用activity中的变量来保存数据,以便用于绘制(渲染等)缩放效果,这些操作可以在onTouch(...)完成。

public class TouchActivity extends Activity implements OnTouchListener

private float mScaleSpan = 1.0f;

private ScaleGestureDetector mScaleDetector;

...

public boolean onTouch(View v, MotionEvent event) {

mScaleDetector.onTouchEvent(event);

// 在这里通过mScaleSpan 的值来完成你想要的操作

// Perform your magic with mScaleSpan now!

...

return true; // indicate event was handled

}

private class ScaleListener extends ScaleGestureDetector.SimpleOnScaleGestureListener {

@Override

public boolean onScale(ScaleGestureDetector detector) {

mScaleSpan = detector.getCurrentSpan(); // average distance between fingers

return true; // indicate event was handled

}

}

}

保存两个手势之间的状态detector.getCurrentSpan() 返回的始终是两个手指之间的距离。因此我们使用ScaleGestureDetector.getScaleFactor()同时将=变成*=。

public class TouchActivity extends Activity implements OnTouchListener

private float mScaleFactor = 1.0f;

...

private class ScaleListener extends ScaleGestureDetector.SimpleOnScaleGestureListener {

@Override

public boolean onScale(ScaleGestureDetector detector) {

mScaleFactor *= detector.getScaleFactor(); // scale change since previous event

return true; // indicate event was handled

}

}

}

Almeros(作者自己)的手势检测类

ok,现在你学会了以面向对象的方式来处理安卓中标准的多点触摸手势了。我所要介绍的手势处理类也是相同的使用方法。我将首先介绍两个我自定义的手势处理类。

RotateGestureDetector只有两只以上的手指触摸屏幕才会产生旋转事件,下面是RotateGestureDetector的使用

public class TouchActivity extends Activity implements OnTouchListener {

private float mRotationDegrees = 0.f;

...

private class RotateListener extends RotateGestureDetector.SimpleOnRotateGestureListener {

@Override

public boolean onRotate(RotateGestureDetector detector) {

mRotationDegrees -= detector.getRotationDegreesDelta();

return true;

}

}

...

}

MoveGestureDetector的用法其实这是一个简化了操作流程的手势识别类,即便没有这个你也可以处理还,但是使用MoveGestureDetector可以让代码变得更简单。

public class TouchActivity extends Activity implements OnTouchListener {

private float mFocusX = 0.f;

private float mFocusY = 0.f;

...

private class MoveListener extends MoveGestureDetector.SimpleOnMoveGestureListener {

@Override

public boolean onMove(MoveGestureDetector detector) {

PointF d = detector.getFocusDelta();

mFocusX += d.x;

mFocusY += d.y;

// mFocusX = detector.getFocusX();

// mFocusY = detector.getFocusY();

return true;

}

}

...

}

所有的手势识别类结合在一起...

import com.almeros.android.multitouch.gesturedetectors.MoveGestureDetector;

import com.almeros.android.multitouch.gesturedetectors.RotateGestureDetector;

public class TouchActivity extends Activity implements OnTouchListener {

...

private float mScaleFactor = 1.0f;

private float mRotationDegrees = 0.f;

private float mFocusX = 0.f;

private float mFocusY = 0.f;

private ScaleGestureDetector mScaleDetector;

private RotateGestureDetector mRotateDetector;

private MoveGestureDetector mMoveDetector;

@Override

public void onCreate(Bundle savedInstanceState) {

...

// Setup Gesture Detectors

mScaleDetector = new ScaleGestureDetector(getApplicationContext(), new ScaleListener());

mRotateDetector = new RotateGestureDetector(getApplicationContext(), new RotateListener());

mMoveDetector = new MoveGestureDetector(getApplicationContext(), new MoveListener());

}

public boolean onTouch(View v, MotionEvent event) {

mScaleDetector.onTouchEvent(event);

mRotateDetector.onTouchEvent(event);

mMoveDetector.onTouchEvent(event);

// Mmmmmhhhagic!!!

//  with: mScaleFactor, mRotationDegrees, mFocusX and mFocusY

...

return true; // indicate event was handled

}

private class ScaleListener extends ScaleGestureDetector.SimpleOnScaleGestureListener {

@Override

public boolean onScale(ScaleGestureDetector detector) {

mScaleFactor *= detector.getScaleFactor(); // scale change since previous event

return true;

}

}

private class RotateListener extends RotateGestureDetector.SimpleOnRotateGestureListener {

@Override

public boolean onRotate(RotateGestureDetector detector) {

mRotationDegrees -= detector.getRotationDegreesDelta();

return true;

}

}

private class MoveListener extends MoveGestureDetector.SimpleOnMoveGestureListener {

@Override

public boolean onMove(MoveGestureDetector detector) {

PointF d = detector.getFocusDelta();

mFocusX += d.x;

mFocusY += d.y;

return true;

}

}

}翻译自 http://code.almeros.com/android-multitouch-gesture-detectors#.VNrg7_mSwTx

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值