今天想实现这个功能,但只是利用现有的onTouchEvent和GestureDetector感觉做起来有些纠结,原来好像也尝试过,最后搞的程序有点乱,不好维护,那么就利用一下Android程序员最大的优势——源码。
    首先想到的ListView既支持点击又支持拖动,就去看源码,首先找的突破点就是:
    android.view.ViewTreeObserver.OnTouchModeChangeListener
    里面只定义了一个方法;
    public void onTouchModeChanged(boolean isInTouchMode);
    然后就看了一下ViewTreeObserver,发现除了add等并没有相关的内容,然后就找到ListView的父类android.widget.AbsListView,其中实现了该接口。这里面比较复杂就不详细介绍了,结合OnTouchEvent和onTouchModeChanged能看出它的实现机制,但大致看完没有发现很好的解决问题的办法,由于快回去了,又想尽快解决,这时候就想到了手势识别的类android.view.GestureDetector,其实看它的OnTouchEvent要轻松的多,跟前面的实现机制都很像,但相对简单,不过在这不可能找到问题的直接解决办法,但是理解了GestureDetector的事件分发机制和情况,用起来OnGestureListener就会清晰的多。之后就用最基本的实现机制模拟了两个事件的处理,这里说模拟是指的其实并没有真正完全区分,关于这方面觉着较为复杂,还没理清,应该深入看ListView会有具体的实现。好了,直接贴代码吧,上面几个类可以帮助解决这个问题,也可以深入研究,具体的时候并没有用到handler,如果要响应更多的方法的时候这种机制就很有用了,方便扩展。下面直接展示下代码,也比较简单,就不过多解释了,这里理解为滑动20像素才认为是滑动事件来模拟,只是这次看起来比较清晰,就记录一下。
 
Java代码  
       //---------------------------------------------------------------------------  
// 触屏与滑动(仅区分滑动和触屏,如果增加双击等时间需要重新考虑逻辑处理)  
//---------------------------------------------------------------------------  
  
private GestureDetector gestureDetector;        //用手势识别  
  
//表明没有手势事件  
private final int TOUCH_MODE_REST = -1;   
//表明触摸了屏幕  
private final int TOUCH_MODE_DOWN = 0;  
//表明发生了scroll,但仍需进一步确认是否是滑动事件  
private final int TOUCH_MODE_SCROLLCHECK = 1;     
//当前为滑动状态  
private final int TOUCH_MODE_SCROLL = 2;  
  
private int touchMode;         //当前touch的状态,利用onDown、OnScroll和ActionUP来区分滑动和触屏  
private int tempOffsetX = 0;   //定义为scroll之前需要先存储偏移  
 
Java代码:  
  1. @Override
  2. public boolean onTouchEvent(MotionEvent event) {
  3. if(event.getAction()==MotionEvent.ACTION_UP){
  4. try {
  5. return handleActionUP(event);
  6. } catch (InaccurateScrollActionHandleException e) {
  7. // TODO Auto-generated catch block
  8. Log.e("DigitBusScreen.onTouchEvent", "Use handleActionUP wrong place");
  9. return false;
  10. }
  11. }
  12. return gestureDetector.onTouchEvent(event);
  13. }
 
Java代码:  
  1. @Override
  2. public boolean onDown(MotionEvent arg0) {
  3. // TODO Auto-generated method stub
  4. touchMode = TOUCH_MODE_DOWN;
  5. return true;
  6. }
  7. @Override
  8. public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX,
  9. float distanceY) {
  10. // TODO Auto-generated method stub
  11. switch(touchMode){
  12. case TOUCH_MODE_DOWN:
  13. case TOUCH_MODE_SCROLLCHECK:
  14. if(Math.abs(tempOffsetX+distanceX)<20){
  15. tempOffsetX += distanceX;
  16. touchMode = TOUCH_MODE_SCROLLCHECK;
  17. }else{
  18. touchMode = TOUCH_MODE_SCROLL;
  19. tempOffsetX = 0;
  20. }
  21. break;
  22. case TOUCH_MODE_SCROLL:
  23. if(distanceX!=0 && (offsetX-distanceX<=0)
  24. && (offsetX-distanceX>=-(offsetX+(actualLengthBetweenStation+Positions.getStationXLength())*numberOfStation))){
  25. for(Sprite sprite:sprites){
  26. if(sprite instanceof ScrollSprite)
  27. ((ScrollSprite)sprite).scrollChangeOffset(-distanceX, 0);
  28. }
  29. offsetX += -distanceX;
  30. }
  31. break;
  32. }
  33. return true;
  34. }
  35. /**
  36. * 处理ACTION_UP的MotionEvent
  37. * @param event
  38. * @return
  39. * @throws InaccurateScrollActionHandleException
  40. */
  41. private boolean handleActionUP(MotionEvent event) throws InaccurateScrollActionHandleException{
  42. if(event.getAction()!=MotionEvent.ACTION_UP)
  43. throw new InaccurateScrollActionHandleException();
  44. switch(touchMode){
  45. case TOUCH_MODE_SCROLLCHECK:
  46. tempOffsetX = 0;
  47. case TOUCH_MODE_DOWN:
  48. super.onTouchEvent(event);
  49. break;
  50. }
  51. touchMode = TOUCH_MODE_REST;
  52. return true;
  53. }

Android 区别普通Touch方法和Scroll的更多相关文章

  1. Junit 注解 类加载器 .动态代理 jdbc 连接池 DButils 事务 Arraylist Linklist hashset 异常 哈希表的数据结构,存储过程 Map Object String Stringbufere File类 文件过滤器_原理分析 flush方法和close方法 序列号冲突问题

    Junit 注解 3).其它注意事项: 1).@Test运行的方法,不能有形参: 2).@Test运行的方法,不能有返回值: 3).@Test运行的方法,不能是静态方法: 4).在一个类中,可以同时定 ...

  2. Android HTTP实例 使用GET方法和POST方法发送请求

    Android HTTP实例 使用GET方法和POST方法发送请求 Web程序:使用GET和POST方法发送请求 首先利用MyEclispe+Tomcat写好一个Web程序,实现的功能就是提交用户信息 ...

  3. ThinkPHP的D方法和M方法的区别

    M方法和D方法的区别 ThinkPHP 中M方法和D方法都用于实例化一个模型类,M方法 用于高效实例化一个基础模型类,而 D方法 用于实例化一个用户定义模型类. 使用M方法 如果是如下情况,请考虑使用 ...

  4. wait方法和sleep方法的区别

    一.概念.原理.区别 Java中的多线程是一种抢占式的机制而不是分时机制.线程主要有以下几种状态:可运行,运行,阻塞,死亡.抢占式机制指的是有多个线程处于可运行状态,但是只有一个线程在运行.      ...

  5. M方法和D方法的区别

    M方法和D方法的区别 ThinkPHP 中M方法和D方法都用于实例化一个模型类,M方法 用于高效实例化一个基础模型类,而 D方法 用于实例化一个用户定义模型类. 使用M方法 如果是如下情况,请考虑使用 ...

  6. ThinkPHP 中M方法和D方法的具体区别(转)

    M方法和D方法的区别 ThinkPHP 中M方法和D方法都用于实例化一个模型类,M方法 用于高效实例化一个基础模型类,而 D方法 用于实例化一个用户定义模型类. 使用M方法 如果是如下情况,请考虑使用 ...

  7. synchronized 修饰在 static方法和非static方法的区别

    Java中synchronized用在静态方法和非静态方法上面的区别 在Java中,synchronized是用来表示同步的,我们可以synchronized来修饰一个方法.也可以synchroniz ...

  8. JAVA反射中的getFields()方法和getDeclaredFields ()方法的区别

    JAVA反射中的getFields()方法和getDeclaredFields ()方法的区别   关于获取类的字段有两种方式:getFields()和getDeclaredFields().我们先来 ...

  9. Exception 的 toString() 方法和 getMessage() 方法的区别

    Exception 的 toString() 方法和 getMessage() 方法的区别: 在开发的过程中打印错误日志时尽量使用e.toString() 方法, 因为当错误为空指针时 e.getMe ...

随机推荐

  1. JS数组随机排序

    var arr=[1,2,3,4,5]; arr.sort(function(a,b){ var v=Math.random()>0.5?1:-1; console.log(a,b,v); re ...

  2. StackTrace,Trim

    一: Environment.StackTrace 可能我们看到最多的就是catch中的e参数,里面会有一个StackTrace,然后不可否认的这玩意太有用了,它会把调用堆栈 中的信息输出出来,有了它 ...

  3. 【Unity3D基础教程】给初学者看的Unity教程(六):理解Unity的新GUI系统(UGUI)

    作者:王选易,出处:http://www.cnblogs.com/neverdie/ 欢迎转载,也请保留这段声明.如果你喜欢这篇文章,请点推荐.谢谢! 理解UGUI的基础架构 UGUI是Unity在4 ...

  4. MySQL数据库InnoDB存储引擎多版本控制(MVCC)实现原理分析

    文/何登成 导读:   来自网易研究院的MySQL内核技术研究人何登成,把MySQL数据库InnoDB存储引擎的多版本控制(简称:MVCC)实现原理,做了深入的研究与详细的文字图表分析,方便大家理解I ...

  5. MySQL中char(36)被认为是GUID导致的BUG及解决方案

    MySQL中char(36)被认为是GUID导致的BUG及解决方案 有时候在使用Toad或在程序中,偶尔会遇到如下的错误: System.FormatException GUID 应包含带 4 个短划 ...

  6. MVC View中获取Url参数的值

    如果url是 /home/index?id=3 直接Request就ok. Razor方法 @Html.ViewContext.RouteData.Values["id"] @Re ...

  7. Spring使用拦截器支持国际化(转)

    Spring使用拦截器支持国际化很方便,使用时只需要两个步骤: 一.spring配置 具体配置方式如下: <!-- 资源文件绑定器,文件名称:messages.properties(没有找到时的 ...

  8. linux包之procps之pmap命令

    名称:       pmap - report memory map of a process(查看进程的内存映像信息)用法       pmap [ -x | -d ] [ -q ] pids... ...

  9. TKinter布局之pack

    pack布局非常简单,不用做过多的设置,直接使用一个 pack 函数就可以了. 1.我们使用 pack 函数的时候,默认先使用的放到上面,然 后 依次向下排,它会给我们的组件一个自认为合适的位置 和大 ...

  10. html之filedset标签

    fieldset 元素可将表单内的相关元素分组,当一组表单元素放到 <fieldset> 标签内时,浏览器会以特殊方式来显示它们,它们可能有特殊的边界.3D 效果,或者甚至可创建一个子表单 ...