From:http://www.dewen.org/q/2438/android%E8%A7%A6%E5%B1%8F%E4%BA%8B%E4%BB%B6%E5%A4%84%E7%90%86onInterceptTouchEvent%E7%9A%84%E9%97%AE%E9%A2%98

android官方文档有个标准解释,现摘录过来:
首先,看Android的官方文档正解

            
  1. onInterceptTouchEvent()与onTouchEvent()的机制:
  2.   1. down事件首先会传递到onInterceptTouchEvent()方法
  3.   2. 如果该ViewGrouponInterceptTouchEvent()在接收到down事件处理完成之return false,那么后续的move, up等事件将继续会先传递给该ViewGroup,之后才和down事件一样传递给最终的目标viewonTouchEvent()处理
  4.   3. 如果该ViewGrouponInterceptTouchEvent()在接收到down事件处理完成之后return true,那么后续的move, up等事件将不再传递给onInterceptTouchEvent(),而是和down事件一样传递给该ViewGrouponTouchEvent()处理,注意,目标view将接收不到任何事件。
  5.   4. 如果最终需要处理事件的viewonTouchEvent()返回了false,那么该事件将被传递至其上一层次的viewonTouchEvent()处理
  6.   5. 如果最终需要处理事件的view onTouchEvent()返回了true,那么后续事件将可以继续传递给该viewonTouchEvent()处理。

仅仅看这个官方文档解释,就能理解清楚这两个函数关系以及用途的绝对是富有经验的framework高手。
否则,一定需要一个案例来阐释。假设我们有这样一个layout,非常典型的

            
  1. <com.test.LayoutView1 xmlns:android="http://schemas.android.com/apk/res/android"
  2. android:orientation="vertical" android:layout_width="fill_parent"
  3. android:layout_height="fill_parent">
  4. <com.test.LayoutView2
  5. android:orientation="vertical" android:layout_width="fill_parent"
  6. android:layout_height="fill_parent" android:gravity="center">
  7. <com.test.MyTextView
  8. android:layout_width="wrap_content" android:layout_height="wrap_content"
  9. />
  10. </com.test.LayoutView2>
  11. </com.test.LayoutView1>

用一个示例图来解释这个layout:


通常外围的layoutview1,layoutview2,只是布局的容器不需要响应触屏的点击事件,仅仅Mytextview需要相应点击。但这只是一般情况,一些特殊的布局可能外围容器也要响应,甚至不让里面的mytextview去响应。更有特殊的情况是,动态更换响应对象。
那么首先看一下默认的触屏事件的在两个函数之间的传递流程。如下图:

如果仅仅想让MyTextView来响应触屏事件,让MyTextView的OnTouchEvent返回true,那么事件流就变成如下图,可以看到layoutview1,layoutview2已经不能进入OnTouchEvent:

另外一种情况,就是外围容器想独自处理触屏事件,那么就应该在相应的onInterceptTouchEvent函数中返回true,表示要截获触屏事件,比如layoutview1作截获处理,处理流变成如下图:

以此类推,我们可以得到各种具体的情况,整个layout的view类层次中都有机会截获,而且能看出来外围的容器view具有优先截获权。

当我们去做一些相对来讲具有更复杂的触屏交互效果的应用时候,经常需要动态变更touch event的处理对象,比如launcher待机桌面和主菜单(见下图),从滑动屏幕开始到停止滑动过程当中,只有外围的容器view才可以处理touch event,否则就会误点击上面的应用图标或者widget.反之在静止不动的状态下则需要能够响应图标(子view)的touch事件。摘取framework中abslistview代码如下

            
  1. public boolean onInterceptTouchEvent(MotionEvent ev) {
  2. int action = ev.getAction();
  3. switch (action & MotionEvent.ACTION_MASK) {
  4. case MotionEvent.ACTION_DOWN: {
  5. if (touchMode == TOUCH_MODE_FLING) {
  6. return true; //fling状态,截获touch,因为在滑动状态,不让子view处理
  7. }
  8. break;
  9. }
  10. case MotionEvent.ACTION_MOVE: {
  11. switch (mTouchMode) {
  12. case TOUCH_MODE_DOWN:
  13. final int pointerIndex = ev.findPointerIndex(mActivePointerId);
  14. final int y = (int) ev.getY(pointerIndex);
  15. if (startScrollIfNeeded(y - mMotionY)) {
  16. return true;//开始滑动状态,截获touch事件,不让子view处理
  17. }
  18. break;
  19. }
  20. break;
  21. }
  22. }

总结:

仅仅通过概览性的官方文档是很难理解onInterceptTouchEvent函数的用途的,只有通过演绎这个抽象的规则,配以图文才能获取这个重要的知识。很显然,默认是返回false,不做截获。返回true之后,事件流的后端控件就没有机会处理touch事件了,把默认的事件流中每个处理函数看作一个节点,这个节点只要返回true, 后续的事件就被截止了,这样想就很好理解。


更多相关文章

  1. EditText点击事件——弹出单选框
  2. 第三十六天 一乐在其中—Android的按钮单击事件及监听器的实现方
  3. Android 依赖注入函数库Roboguice(一)
  4. Android中点击事件的四种写法详解
  5. android:如何在java代码中覆盖webview中的javascript事件
  6. Android 关于嵌套listView时onItemClick事件不响应的解决办法
  7. Android webkit keyevent 事件传递过程
  8. android屏幕触摸事件机制

随机推荐

  1. android中布局使用大全
  2. android 用代码画虚线边框背景
  3. Android(安卓)相对布局
  4. Android(安卓)API Level对应Android版本
  5. android 实现透明按钮
  6. Android隐藏状态栏和标题栏,相当于全屏效
  7. Android剖析和运行机制
  8. 系统自带theme
  9. android 布局居中
  10. android list item divider line