引用:http://blog.csdn.net/rmm0001/article/details/6624525

  1. publicclassGestureTestextendsActivityimplementsOnTouchListener,OnGestureListener {
  2. @Override
  3. protectedvoidonCreate(BundlesavedInstanceState){
  4. super.onCreate(savedInstanceState);
  5. setContentView(R.layout.main);
  6. //initTextView
  7. TextViewtv=(TextView)findViewById(R.id.page);
  8. //setOnTouchListeneronTextView
  9. tv.setOnTouchListener(this);
  10. //showsometext
  11. tv.setText(R.string.text);
  12. }
  13. @Override
  14. publicbooleanonTouch(Viewv,MotionEventevent){
  15. Toast.makeText(this,"onTouch",Toast.LENGTH_SHORT).show();
  16. returnfalse;
  17. }
  18. 我们给TextView的实例tv设定了一个onTouchListener,因为GestureTest类实现了OnTouchListener接口,所以简单的给一个this作为参数即可。onTouch方法则是实现了OnTouchListener中的抽象方法,我们只要在这里添加逻辑代码即可在用户触摸屏幕时做出响应,就像我们这里所做的——打出一个提示信息。
  19. 这里,我们可以通过MotionEvent的getAction()方法来获取Touch事件的类型,包括ACTION_DOWN,ACTION_MOVE,ACTION_UP,和ACTION_CANCEL。ACTION_DOWN是指按下触摸屏,ACTION_MOVE是指按下触摸屏后移动受力点,ACTION_UP则是指松开触摸屏,ACTION_CANCEL不会由用户直接触发(所以不在今天的讨论范围,请参考ViewGroup.onInterceptTouchEvent(MotionEvent))。借助对于用户不同操作的判断,结合getRawX()、getRawY()、getX()和getY()等方法来获取坐标后,我们可以实现诸如拖动某一个按钮,拖动滚动条等功能。待机可以看看MotionEvent类的文档,另外也可以看考TouchPaint例子。
  20. 回到今天所要说的重点,当我们捕捉到Touch操作的时候,如何识别出用户的Gesture?这里我们需要GestureDetector.OnGestureListener接口的帮助,于是我们的GestureTest类就变成了这个样子。
  21. Java代码
  22. publicclassGestureTestextendsActivityimplementsOnTouchListener,
  23. OnGestureListener{
  24. ....
  25. }
  26. 随后,在onTouch()方法中,我们调用GestureDetector的onTouchEvent()方法,将捕捉到的MotionEvent交给GestureDetector来分析是否有合适的callback函数来处理用户的手势。
  27. Java代码
  28. @Override
  29. public
  30. booleanonTouch(Viewv,MotionEventevent){
  31. //OnGestureListenerwillanalyzesthegivenmotionevent
  32. returnmGestureDetector.onTouchEvent(event);
  33. }
  34. 接下来,我们实现了以下6个抽象方法,其中最有用的当然是onFling()、onScroll()和onLongPress()了。我已经把每一个方法代表的手势的意思写在了注释里,大家看一下就明白了。
  35. //用户轻触触摸屏,由1个MotionEventACTION_DOWN触发
  36. Java代码
  37. @Override
  38. publicbooleanonDown(MotionEvente){
  39. //TODOAuto-generatedmethodstub
  40. Toast.makeText(this,"onDown",Toast.LENGTH_SHORT).show();
  41. returnfalse;
  42. }
  43. //用户轻触触摸屏,尚未松开或拖动,由一个1个MotionEventACTION_DOWN触发
  44. //注意和onDown()的区别,强调的是没有松开或者拖动的状态
  45. @Override
  46. publicvoidonShowPress(MotionEvente){
  47. //TODOAuto-generatedmethodstub
  48. }
  49. //用户(轻触触摸屏后)松开,由一个1个MotionEventACTION_UP触发
  50. Java代码
  51. @Override
  52. publicbooleanonSingleTapUp(MotionEvente){
  53. //TODOAuto-generatedmethodstub
  54. returnfalse;
  55. }
  56. //用户按下触摸屏、快速移动后松开,由1个MotionEventACTION_DOWN,多个ACTION_MOVE,1个ACTION_UP触发
  57. Java代码
  58. @Override
  59. publicbooleanonFling(MotionEvente1,MotionEvente2,floatvelocityX,floatvelocityY){
  60. //TODOAuto-generatedmethodstub
  61. returnfalse;
  62. }
  63. //用户长按触摸屏,由多个MotionEventACTION_DOWN触发
  64. @Override
  65. public
  66. voidonLongPress(MotionEvente){
  67. //TODOAuto-generatedmethodstub
  68. }
  69. //用户按下触摸屏,并拖动,由1个MotionEventACTION_DOWN,多个ACTION_MOVE触发
  70. @Override
  71. public
  72. booleanonScroll(MotionEvente1,MotionEvente2,floatdistanceX,floatdistanceY){
  73. //TODOAuto-generatedmethodstub
  74. returnfalse;
  75. }
  76. 我们来试着做一个onFling()事件的处理吧,onFling()方法中每一个参数的意义我写在注释中了,需要注意的是Fling事件的处理代码中,除了第一个触发Fling的ACTION_DOWN和最后一个ACTION_MOVE中包含的坐标等信息外,我们还可以根据用户在X轴或者Y轴上的移动速度作为条件。比如下面的代码中我们就在用户移动超过100个像素,且X轴上每秒的移动速度大于200像素时才进行处理。
  77. Java代码
  78. @Override
  79. publicbooleanonFling(MotionEvente1,MotionEvente2,floatvelocityX,floatvelocityY){
  80. //参数解释:
  81. //e1:第1个ACTION_DOWNMotionEvent
  82. //e2:最后一个ACTION_MOVEMotionEvent
  83. //velocityX:X轴上的移动速度,像素/秒
  84. //velocityY:Y轴上的移动速度,像素/秒
  85. //触发条件:
  86. //X轴的坐标位移大于FLING_MIN_DISTANCE,且移动速度大于FLING_MIN_VELOCITY个像素/秒
  87. if(e1.getX()-e2.getX()>FLING_MIN_DISTANCE&&Math.abs(velocityX)>FLING_MIN_VELOCITY){
  88. //Flingleft
  89. Toast.makeText(this,"FlingLeft",Toast.LENGTH_SHORT).show();
  90. }elseif(e2.getX()-e1.getX()>FLING_MIN_DISTANCE&&Math.abs(velocityX)>FLING_MIN_VELOCITY){
  91. //Flingright
  92. Toast.makeText(this,"FlingRight",Toast.LENGTH_SHORT).show();
  93. }
  94. returnfalse;
  95. }
  96. 问题是,这个时候如果我们尝试去运行程序,你会发现我们根本得不到想要的结果,跟踪代码的执行的会发现onFling()事件一直就没有被捕捉到。这正是一开始困扰我的问题,这到底是为什么呢?
  97. 我在讨论组的Gesturedetection这个帖子里找到了答案,即我们需要在onCreate中tv.setOnTouchListener(this);之后添加如下一句代码。
  98. tv.setLongClickable(true);
  99. 只有这样,view才能够处理不同于Tap(轻触)的hold(即ACTION_MOVE,或者多个ACTION_DOWN),我们同样可以通过layout定义中的android:longClickable来做到这一点。
  100. 这次遇到的这个问题和上次MapView中setOnKeyListener遇到的问题挺类似,其实都是对SDK的了解不够全面,遇到了一次记住了就好。不过话说回来,Google在文档方面确实需要加强了,起码可以在OnGestureListener中说明需要满足那些条件才可以保证手势被正确识别。

Android里有两个类
android.view.GestureDetector
android.view.GestureDetector.SimpleOnGestureListener

(另外android.widget.Gallery好像是更牛x的OnGestureListener )

1)
新建一个类继承SimpleOnGestureListener,HahaGestureDetectorListener
可以实现以下event事件。

boolean onDoubleTap(MotionEvent e)
解释:双击的第二下Touch down时触发

boolean onDoubleTapEvent(MotionEvent e)
解释:双击的第二下Touch down和up都会触发,可用e.getAction()区分。

boolean onDown(MotionEvent e)
解释:Touch down时触发

boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY)
解释:Touch了滑动一点距离后,up时触发。

void onLongPress(MotionEvent e)
解释:Touch了不移动一直Touch down时触发

boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY)
解释:Touch了滑动时触发。

void onShowPress(MotionEvent e)
解释:Touch了还没有滑动时触发
(与onDown,onLongPress比较
onDown只要Touch down一定立刻触发。

而Touchdown后过一会没有滑动先触发onShowPress再是onLongPress。

所以Touchdown后一直不滑动,onDown->onShowPress->onLongPress这个顺序触发。


boolean onSingleTapConfirmed(MotionEvent e)
boolean onSingleTapUp(MotionEvent e)
解释:上面这两个函数都是在touch down后又没有滑动(onScroll),又没有长按(onLongPress),然后Touchup时触发。

点击一下非常快的(不滑动)Touchup:
onDown->onSingleTapUp->onSingleTapConfirmed

点击一下稍微慢点的(不滑动)Touchup:
onDown->onShowPress->onSingleTapUp->onSingleTapConfirmed


2)在view的新建一个GestureDetector的对象。
构造函数里
gestureDetector = new GestureDetector(new HahaGestureDetectorListener());

然后在View的onTouchEvent里以下这样用,就可以在刚才1)弄的事件里写自己的代码了。
@Override
public boolean onTouchEvent(MotionEvent event) {
gestureDetector.onTouchEvent(event);
}

下面Android123一起用Android 2.0或以上SDK中的方法来实现如何通过应用层支持多点触控操作,对于常规的控件触控操作在内部为View的setOnTouchListener()接口实现的onTouchEvent()方法来处理。对于onTouchEvent方法的参数MotionEvent我们可以详细处理来实现对多点触控的了解,比如

  event.getAction() //获取触控动作比如ACTION_DOWN

  event.getPointerCount(); //获取触控点的数量,比如2则可能是两个手指同时按压屏幕

  event.getPointerId(nID); //对于每个触控的点的细节,我们可以通过一个循环执行getPointerId方法获取索引

  event.getX(nID); //获取第nID个触控点的x位置

  event.getY(nID); //获取第nID个点触控的y位置

  event.getPressure(nID); //LCD可以感应出用户的手指压力,当然具体的级别由驱动和物理硬件决定的

  event.getDownTime() //按下开始时间

  event.getEventTime() // 事件结束时间

  event.getEventTime()-event.getDownTime()); //总共按下时花费时间

更多相关文章

  1. android 设置默认launcher 附上代码
  2. Android通过代码自动连接WiFi
  3. Android service: startService的代码实现
  4. 【代码】利用Android的Log 演示一个activity的生命周期
  5. Android Robotium的自动化代码
  6. Android代码实现飞行模式的打开
  7. Google用户登录界面 Android实现
  8. Android对应用程序的资源文件xml解析的源代码在哪里

随机推荐

  1. MySQL横纵表相互转化操作实现方法
  2. centos7下安装mysql6初始化安装密码的方
  3. 关于MYSQL 你需要知道的数据类型和操作数
  4. Mysql索引类型与基本用法实例分析
  5. MySql数据库基础知识点总结
  6. MySQL自动停机的问题处理实战记录
  7. MySQL5.6.40在CentOS7 64下安装过程详解
  8. MySQL最佳实践之分区表基本类型
  9. MySQL分区表的基本入门教程
  10. MySQL分区表的最佳实践指南