尊重原创:http://blog.csdn.net/yuanzeyao/article/details/38025165

资源下载:http://download.csdn.net/detail/yuanzeyao2008/7660997

在前一篇文章中,我主要解说了Android源代码中的Touch事件的传递过程,如今我想使用一个demo以及一个实例来学习一下Andorid中的Touch事件处理过程。

在Android系统中。和Touch事件分发和处理紧密相关的三个函数例如以下:

(1) public boolean dispatchTouchEvent(MotionEvent ev)

(2) public boolean onInterceptTouchEvent(MotionEvent ev)

(3) public boolean onTouchEvent(MotionEvent event)





这三个方法我在前一篇文章中都对他们的源代码进行了分析:方法1主要是对Touch事件进行分发,方法2主要是对Touch事件进行拦截,方法3是对Touch事件进行处理

这三个方法主要存在于ViewGroup,View,Activity中,详细情况例如以下图:

ViewGroup

View

Activity

dispatchTouchEvent

onInterceptTouchEvent

onTouchEvent

以下我们就使用一个demo来看看这些方法的运行流程:

自己定义一个类:MyLayoutFirst.java

  1. public class MyLayoutFirst extends LinearLayout
  2. {
  3. private static final String TAG = "MyLayoutFirst";
  4. public MyLayoutFirst(Context context, AttributeSet attrs)
  5. {
  6. super(context, attrs);
  7. }
  8.  
  9. @Override
  10. public boolean onInterceptTouchEvent(MotionEvent ev)
  11. {
  12. Log.w("yzy", "MyLayoutFirst->onInterceptTouchEvent->"+MyUtils.getActionName(ev));
  13. return super.onInterceptTouchEvent(ev);
  14. }
  15.  
  16. @Override
  17. public boolean onTouchEvent(MotionEvent event)
  18. {
  19. Log.e("yzy", "MyLayoutFirst->onTouchEvent->"+MyUtils.getActionName(event));
  20. return super.onTouchEvent(event);
  21. }
  22.  
  23. @Override
  24. public boolean dispatchTouchEvent(MotionEvent ev)
  25. {
  26. Log.i("yzy", "MyLayoutFirst->dispatchTouchEvent->"+MyUtils.getActionName(ev));
  27. return super.dispatchTouchEvent(ev);
  28. }
  29.  
  30. }

自己定义一个类;MyLayoutSecond.java

  1. public class MyLayoutSecond extends LinearLayout
  2. {
  3. private static final String TAG = "MyLayoutSecond";
  4. public MyLayoutSecond(Context context, AttributeSet attrs)
  5. {
  6. super(context, attrs);
  7. }
  8.  
  9. @Override
  10. public boolean onTouchEvent(MotionEvent event)
  11. {
  12. Log.e("yzy", "MyLayoutSecond->MyLayoutSecond->"+MyUtils.getActionName(event));
  13. return super.onTouchEvent(event);
  14. }
  15.  
  16. @Override
  17. public boolean onInterceptTouchEvent(MotionEvent ev)
  18. {
  19. Log.w("yzy", "MyLayoutSecond->onInterceptTouchEvent->"+MyUtils.getActionName(ev));
  20. return super.onInterceptTouchEvent(ev);
  21. }
  22.  
  23. @Override
  24. public boolean dispatchTouchEvent(MotionEvent ev)
  25. {
  26. Log.i("yzy", "MyLayoutSecond->dispatchTouchEvent->"+MyUtils.getActionName(ev));
  27. return super.dispatchTouchEvent(ev);
  28. }
  29.  
  30. }

增加到main_layout.xml中

  1. <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
  2. xmlns:tools="http://schemas.android.com/tools"
  3. android:layout_width="match_parent"
  4. android:layout_height="match_parent"
  5. >
  6.  
  7. <com.event.demo.MyLayoutFirst
  8. android:id="@+id/layout_first"
  9. android:layout_width="match_parent"
  10. android:layout_height="match_parent"
  11. android:background="#FF0000"
  12. >
  13. <com.event.demo.MyLayoutSecond
  14. android:id="@+id/layout_second"
  15. android:layout_width="320dip"
  16. android:layout_height="120dip"
  17. android:layout_gravity="center"
  18. android:background="#0000FF"
  19. >
  20.  
  21. </com.event.demo.MyLayoutSecond>
  22. </com.event.demo.MyLayoutFirst>
  23.  
  24. </RelativeLayout>

MainActivity中增加onTouchEvent方法

  1. public class MainActivity extends Activity
  2. {
  3.  
  4. @Override
  5. protected void onCreate(Bundle savedInstanceState)
  6. {
  7. super.onCreate(savedInstanceState);
  8. setContentView(R.layout.activity_main);
  9. }
  10.  
  11. @Override
  12. public boolean onCreateOptionsMenu(Menu menu)
  13. {
  14. // Inflate the menu; this adds items to the action bar if it is present.
  15. getMenuInflater().inflate(R.menu.main, menu);
  16. return true;
  17. }
  18.  
  19. @Override
  20. public boolean dispatchTouchEvent(MotionEvent ev)
  21. {
  22. Log.i("yzy", "MainActivity->dispatchTouchEvent->"+MyUtils.getActionName(ev));
  23. return super.dispatchTouchEvent(ev);
  24. }
  25.  
  26. @Override
  27. public boolean onTouchEvent(MotionEvent event)
  28. {
  29. Log.e("yzy", "MainActivity->onTouchEvent->"+MyUtils.getActionName(event));
  30. return super.onTouchEvent(event);
  31. }
  32. }

最后就一个工具类,用来将事件id转换为字符串。

  1. public class MyUtils
  2. {
  3. private static final String TAG = "MyUtils";
  4. public static String getActionName(MotionEvent event)
  5. {
  6. String name="";
  7. switch(event.getAction())
  8. {
  9. case MotionEvent.ACTION_DOWN:
  10. name="ACTION_DOWN";
  11. break;
  12. case MotionEvent.ACTION_MOVE:
  13. name="ACTION_MOVE";
  14. break;
  15. case MotionEvent.ACTION_UP:
  16. name="ACTION_UP";
  17. break;
  18. }
  19. return name;
  20. }
  21. }

执行效果如图:

当中蓝色部分是MyLayoutSecond.java ,红色部分是MyLayoutFirst.java

如今我点击一下蓝色部分:执行结果如图:

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQveXVhbnpleWFv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt="">

从图中能够看出,事件最先被Activity捕获,然后分发给 MyLayoutFirst,MyLayoutFirst首先调用自身的onInterceptTouchEvent推断是否将该事件拦截。因为默认返回是false,所以没有拦截,从而事件分发给了MyLayoutSecond,MyLayoutSecond相同通过dispatchTouchEvent分发出去。分发出去之前相同检查是否被拦截,默认都是没有被拦截的,可是因为MyLayoutSecond是没有子视图的,全部终于事件有自己处理。调用自身的onTouchEvent方法,因为该方法默认返回的是false,所以觉得此事件是没有被消费掉的,继续传递到了MyLayoutFirst中,相同也没有消费这个事件,终于传递到了Mainactivity,继续往后看发现后面的ACTION_MOVE和ACTION_UP并没有传入MyLayoutFirst和MyLayoutSecond,这是因为一旦某一个事件没有被处理,后面的事件是不会被分发的。所以ACTION_MOVE和ACTION_UP直接被MainActivity处理掉了。

以下再看另外一种情况:

MainActivity

MyLayoutFirst

MyLayoutSecond

dispatchTouchEvent

super.dispatchTouchEvent

super.dispatchTouchEvent

super.dispatchTouchEvent

onInterceptTouchEvent

--

true

super.onInterceptTouchEvent(ev)

onTouchEvent

super.onTouchEvent

super.onTouchEvent

super.onTouchEvent

执行结果例如以下:

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQveXVhbnpleWFv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt="">

从图中能够看出,事件传递到了MyLayoutFirst后没有分发到MyLayoutSecond。直接调用自身的onTouchEvent,因为返回的是false,导致事件没有消费,终于传递给了MainActivity,

并且兴许事件也没有传递到MyLayoutFirst和MyLayoutSecond。直接被MainActivity处理

第三种情况:

MainActivity

MyLayoutFirst

MyLayoutSecond

dispatchTouchEvent

super.dispatchTouchEvent

super.dispatchTouchEvent

super.dispatchTouchEvent

onInterceptTouchEvent

--

true

super.onInterceptTouchEvent(ev)

onTouchEvent

super.onTouchEvent

true

super.onTouchEvent

执行结果:

和情况二不同的是MyLayoutFirst的onTouchEvent返回了true。也就是说MyLayoutFirst消费了此事件,所以ACTION_DOWN也没有再传给MainActivity,而且ACTION_MOVE和ACTION_UP

均传给了MyLayoutFirst

第四中情况:

MainActivity

MyLayoutFirst

MyLayoutSecond

dispatchTouchEvent

super.dispatchTouchEvent

super.dispatchTouchEvent

super.dispatchTouchEvent

onInterceptTouchEvent

--

super.onInterceptTouchEvent(ev)

super.onInterceptTouchEvent(ev)

onTouchEvent

super.onTouchEvent

super.onTouchEven

true

执行结果:

发现全部的事件都是传递到了MyLayoutSecond后被消费了

事实上还有非常多其它组合方式。大家假设又兴趣能够自己尝试改变每一个函数的返回值。查看打印结果,这里我就不一一列举了。。。。

最后我会提供一个小demo演示怎样解决滑动冲突,背景例如以下:

一个ViewPager里面包括两个Framgent,有一个Fragment里面有一个HorizontalListView ,怎样滑动冲突?

我就贴出关键代码吧

  1. horizontal=(HorizontalListView)view.findViewById(R.id.hscroll);
  2. horizontal.setOnTouchListener(new OnTouchListener()
  3. {
  4.  
  5. @Override
  6. public boolean onTouch(View arg0, MotionEvent event)
  7. {
  8. if(event.getAction()==MotionEvent.ACTION_DOWN)
  9. {
  10. parent.requestDisallowInterceptTouchEvent(true);
  11. }else if(event.getAction()==MotionEvent.ACTION_UP)
  12. {
  13. parent.requestDisallowInterceptTouchEvent(false);
  14. }
  15. return false;
  16. }
  17. });

增加这段代码就能够避免滑动冲突了,至于为什么大家能够參考我的前曾经文章《Android Touch 事件传递机制具体解释 上》 这两个demo的样例我均会上传下载的

Android Touch事件传递机制具体解释 下的更多相关文章

  1. Android Touch事件传递机制详解 下

    尊重原创:http://blog.csdn.net/yuanzeyao/article/details/38025165 资源下载:http://download.csdn.net/detail/yu ...

  2. Android Touch事件传递机制具体解释 上

    尊重原创:http://blog.csdn.net/yuanzeyao/article/details/37961997 近期总是遇到关于Android Touch事件的问题,如:滑动冲突的问题,曾经 ...

  3. Android touch 事件传递机制

    前言: (1)在自定义view的时候经常会遇到事件拦截处理,比如在侧滑菜单的时候,我们希望在侧滑菜单里面有listview控件,但是我们希望既能左右滑动又能上下滑动,这个时候就需要对触摸的touch事 ...

  4. Android Touch事件传递机制 一: OnTouch,OnItemClick(监听器),dispatchTouchEvent(伪生命周期)

      ViewGroup View  Activity dispatchTouchEvent 有 有 有 onInterceptTouchEvent 有 无 无 onTouchEvent 有 有 有 例 ...

  5. Android Touch事件传递机制通俗讲解

    在讲正题之前我们讲一段有关任务传递的小故事,抛砖迎玉下: 话说一家软件公司,来一个任务,分派给了开发经理去完成: 开发经理拿到,看了一下,感觉好简单,于是 开发经理:分派给了开发组长 开发组长:分派给 ...

  6. Android Touch事件传递机制引发的血案

    尊重原创:http://blog.csdn.net/yuanzeyao/article/details/38942135 关于Android Touch事件传递机制我之前也写过两篇文章,自觉得对Tou ...

  7. Android Touch事件传递机制 二:单纯的(伪生命周期)

    转载于:http://blog.csdn.net/yuanzeyao/article/details/38025165 在前一篇文章中,我主要讲解了Android源码中的Touch事件的传递过程,现在 ...

  8. Android Touch事件传递机制 二:单纯的(伪生命周期) 这个清楚一点

    转载于:http://blog.csdn.net/yuanzeyao/article/details/38025165 在前一篇文章中,我主要讲解了Android源码中的Touch事件的传递过程,现在 ...

  9. (转)Android Touch事件传递机制

    -----来源:http://www.trinea.cn/android/touch-event-delivery-mechanism/ 介绍Android Touch事件的传递机制. 不少朋友私信问 ...

随机推荐

  1. 【bzoj4390】[Usaco2015 dec]Max Flow LCA

    题目描述 Farmer John has installed a new system of N−1 pipes to transport milk between the N stalls in h ...

  2. Pointcut is not well-formed: expecting 'name pattern' at character position 53

    报错内容: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'dataso ...

  3. java写文件的基本操作

    import java.io.BufferedWriter; import java.io.File; import java.io.FileWriter; import java.io.IOExce ...

  4. Java EE 学习(5):IDEA + maven + spring 搭建 web(1)

    参考:http://www.cnblogs.com/lonelyxmas/p/5397422.html http://www.ctolib.com/docs-IntelliJ-IDEA-c--1590 ...

  5. mac 应用程序安装目录

    java 安装目录 :/Library/Java/JavaVirtualMachines/jdk1.8.0_<more numbers>.jdk/Contents/Home maven 安 ...

  6. 【13】vuex2.0 之 state

    Vuex 的核心是 store, 它是一个通过 Vuex.Store 构造函数生成的对象.为什么它会是核心呢?因为我们调用这个构造函数创建store 对象的时候,给它传递参数中包装了state, mu ...

  7. Fence(codeforces 232D)

    题意: 对于给定的a[1..n],定义区间[s,t]和[x,y]"匹配"当且仅当下列条件同时满足:1. t-s=y-x,即长度相同.3. t<x或s>y,即两区间没有交 ...

  8. .NET and php

    原文发布时间为:2011-12-29 -- 来源于本人的百度文章 [由搬家工具导入] http://www.php-compiler.net/blog/2011/phalanger-3-0

  9. [LeetCode] Min Stack 栈

    Design a stack that supports push, pop, top, and retrieving the minimum element in constant time. pu ...

  10. 多线程设计模式 - Future模式

    Future模式是多线程开发中非常常见的一种设计模式,它的核心思想是异步调用.这类似我们日常生活中的在线购物流程,带在购物网看着一件商品时可以提交表单,当订单完成后就可以在家里等待商品送货上门.或者说 ...