Android触摸及手势操作GestureDetector

作者:xyz_lmn 时间:2023-07-31 14:13:42 

现在的智能手机不敢说百分百的都是触摸屏,也应该是百分之九九以上为触摸屏了,触摸屏为我们操作无键盘、无鼠标的手机系统带来了很多的便利。当用户触摸屏幕时会产生很多的触摸事件,down、up、move等等。View类有个View.OnTouchListener内部接口,通过重写他的onTouch(View v, MotionEvent event)方法,我们可以处理一些touch事件,如下:


public class MainActivity extends Activity {
...
// This example shows an Activity, but you would use the same approach if
// you were subclassing a View.
@Override
public boolean onTouchEvent(MotionEvent event){

int action = MotionEventCompat.getActionMasked(event);

switch(action) {
 case (MotionEvent.ACTION_DOWN) :
  Log.d(DEBUG_TAG,"Action was DOWN");
  return true;
 case (MotionEvent.ACTION_MOVE) :
  Log.d(DEBUG_TAG,"Action was MOVE");
  return true;
 case (MotionEvent.ACTION_UP) :
  Log.d(DEBUG_TAG,"Action was UP");
  return true;
 case (MotionEvent.ACTION_CANCEL) :
  Log.d(DEBUG_TAG,"Action was CANCEL");
  return true;
 case (MotionEvent.ACTION_OUTSIDE) :
  Log.d(DEBUG_TAG,"Movement occurred outside bounds " +
    "of current screen element");
  return true;  
 default :
  return super.onTouchEvent(event);
}  
}

OnTouch提供的事件还是相对较简单,如果需要处理一些复杂的手势,用这个接口就会很麻烦,因为我们要根据用户触摸的轨迹去判断是什么手势。Android sdk给我们提供了GestureDetector(Gesture:手势Detector:识别)类,通过这个类我们可以识别很多的手势。


public class GestureDetector extends Object
java.lang.Object
android.view.GestureDetector

GestureDetector属于android.view包,android还提供了android.gesture包支持更多的手势操作,以后我们会介绍到。官方的介绍中使用了GestureDetectorCompat处理手势识别,为什么使用GestureDetectorCompat替换了GestureDetector呢,官方的是这样解释的:

Android触摸及手势操作GestureDetector

 GestureDetectorCompat实例化有下面两种方法:

Android触摸及手势操作GestureDetector   

GestureDetector类对外提供了两个接口:OnGestureListener,OnDoubleTapListener,还有一个内部类SimpleOnGestureListener;SimpleOnGestureListener类是GestureDetector提供给我们的一个更方便的响应不同手势的类,它实现了上述两个接口,该类是static class,也就是说它实际上是一个外部类,我们可以在外部继承这个类,重写里面的手势处理方法。因此实现手势识别有两种方法,一种实现OnGestureListener接口,另一种是使用SimpleOnGestureListener类。

OnGestureListener有下面的几个动作:

按下(onDown): 刚刚手指接触到触摸屏的那一刹那,就是触的那一下。

抛掷(onFling): 手指在触摸屏上迅速移动,并松开的动作。

长按(onLongPress): 手指按在持续一段时间,并且没有松开。

滚动(onScroll): 手指在触摸屏上滑动。

按住(onShowPress): 手指按在触摸屏上,它的时间范围在按下起效,在长按之前。

抬起(onSingleTapUp):手指离开触摸屏的那一刹那。

使用OnGestureListener接口,这样需要重载OnGestureListener接口所有的方法,适合监听所有的手势,正如官方文档提到的“Detecing All Supported Gestures”。


public class MainActivity extends Activity implements
 GestureDetector.OnGestureListener,
 GestureDetector.OnDoubleTapListener{

private static final String DEBUG_TAG = "Gestures";
private GestureDetectorCompat mDetector;

// Called when the activity is first created.
@Override
public void onCreate(Bundle savedInstanceState) {
 super.onCreate(savedInstanceState);
 setContentView(R.layout.activity_main);
 // Instantiate the gesture detector with the
 // application context and an implementation of
 // GestureDetector.OnGestureListener
 mDetector = new GestureDetectorCompat(this,this);
 // Set the gesture detector as the double tap
 // listener.
 mDetector.setOnDoubleTapListener(this);
}

@Override
public boolean onTouchEvent(MotionEvent event){
 this.mDetector.onTouchEvent(event);
 // Be sure to call the superclass implementation
 return super.onTouchEvent(event);
}

@Override
public boolean onDown(MotionEvent event) {
 Log.d(DEBUG_TAG,"onDown: " + event.toString());
 return true;
}

@Override
public boolean onFling(MotionEvent event1, MotionEvent event2,
  float velocityX, float velocityY) {
 Log.d(DEBUG_TAG, "onFling: " + event1.toString()+event2.toString());
 return true;
}

@Override
public void onLongPress(MotionEvent event) {
 Log.d(DEBUG_TAG, "onLongPress: " + event.toString());
}

@Override
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX,
  float distanceY) {
 Log.d(DEBUG_TAG, "onScroll: " + e1.toString()+e2.toString());
 return true;
}

@Override
public void onShowPress(MotionEvent event) {
 Log.d(DEBUG_TAG, "onShowPress: " + event.toString());
}

@Override
public boolean onSingleTapUp(MotionEvent event) {
 Log.d(DEBUG_TAG, "onSingleTapUp: " + event.toString());
 return true;
}

@Override
public boolean onDoubleTap(MotionEvent event) {
 Log.d(DEBUG_TAG, "onDoubleTap: " + event.toString());
 return true;
}

@Override
public boolean onDoubleTapEvent(MotionEvent event) {
 Log.d(DEBUG_TAG, "onDoubleTapEvent: " + event.toString());
 return true;
}

@Override
public boolean onSingleTapConfirmed(MotionEvent event) {
 Log.d(DEBUG_TAG, "onSingleTapConfirmed: " + event.toString());
 return true;
}
}

 这样会造成有些手势动作我们用不到,但是还要重载。SimpleOnGestureListener类的出现为我们解决了这个问题,如果你想“Detecting a Subset of Supported Gestures”,SimpleOnGestureListener是最好的选择。


public class MainActivity extends Activity {

private GestureDetectorCompat mDetector;

@Override
public void onCreate(Bundle savedInstanceState) {
 super.onCreate(savedInstanceState);
 setContentView(R.layout.activity_main);
 mDetector = new GestureDetectorCompat(this, new MyGestureListener());
}

@Override
public boolean onTouchEvent(MotionEvent event){
 this.mDetector.onTouchEvent(event);
 return super.onTouchEvent(event);
}

class MyGestureListener extends GestureDetector.SimpleOnGestureListener {
 private static final String DEBUG_TAG = "Gestures";

@Override
 public boolean onDown(MotionEvent event) {
  Log.d(DEBUG_TAG,"onDown: " + event.toString());
  return true;
 }

@Override
 public boolean onFling(MotionEvent event1, MotionEvent event2,
   float velocityX, float velocityY) {
  Log.d(DEBUG_TAG, "onFling: " + event1.toString()+event2.toString());
  return true;
 }
}
}

最后了我们也解释两个问题:

1、onTouchEvent中为什么使用了MotionEventCompat,而不直接使用MotionEvent。因为MotionEventCompat使更多的Action适配到API 4。

2、Android的view怎么使用手势,方法如下:


View myView = findViewById(R.id.my_view);
 myView.setOnTouchListener(new OnTouchListener() {
  public boolean onTouch(View v, MotionEvent event) {
   // ... Respond to touch events  
  this.mDetector.onTouchEvent(event);
   return super.onTouchEvent(event);
  }
 });
标签:Android,触摸,手势,GestureDetector
0
投稿

猜你喜欢

  • Java实现文件读取和写入过程解析

    2023-06-28 11:35:36
  • Spring实战之属性占位符配置器用法示例

    2021-05-30 22:58:04
  • Android中解决WebView上下滑动监听问题

    2022-04-18 04:45:37
  • 详解Spring Security中的HttpBasic登录验证模式

    2023-12-03 03:58:14
  • JAVA抽象类,接口,内部类详解

    2023-11-09 16:37:25
  • Java基础之并发相关知识总结

    2022-04-24 13:59:05
  • C#使用DirectX.DirectSound播放语音

    2022-08-28 01:22:33
  • Java中类的加载顺序执行结果

    2022-03-12 18:12:35
  • Android Studio 3.3.2 正式版的安装教程图解

    2022-01-13 22:22:34
  • Java反射如何修改private final成员变量值

    2023-09-06 03:43:18
  • Java动态规划之编辑距离问题示例代码

    2023-10-30 00:21:21
  • Android利用FlexboxLayout轻松实现流动布局

    2021-06-24 02:41:53
  • android获取手机唯一标识的方法

    2022-09-16 15:55:39
  • Spring通过<import>标签导入外部配置文件

    2023-03-04 06:43:58
  • Java BigDecimal中divide方法案例详解

    2021-12-31 07:00:29
  • C#学习教程之Socket的简单使用

    2022-09-07 18:15:04
  • Java编写实现坦克大战小游戏

    2023-11-24 09:15:34
  • Mybatis逆向工程运行代码实例

    2021-06-22 04:54:59
  • Kotlin开发Android应用实例详解

    2023-09-11 00:22:50
  • Android onbackpressed实现返回键的拦截和弹窗流程分析

    2021-09-11 09:07:22
  • asp之家 软件编程 m.aspxhome.com