onInterceptTouchEvent与onTouchEvent

之前练习自定义ViewGroup时,用到了onInterceptTouchEvent方法,这个方法与onTouchEvent容易搞不清,特此分享一下这两个方法的使用方法。

1、onInterceptTouchEvent()是用于处理事件,其返回值决定是否允许Touch事件继续向下(子控件)传递。返回True(代表事件在当前的viewGroup中会被处理),则向下传递之路被截断(所有子控件将没有机会参与Touch事件),同时把事件传递给当前的控件的onTouchEvent()处理;返回false,则把事件交给子控件的onInterceptTouchEvent(),以此类推。

2、onTouchEvent()用于处理事件,其返回值决定当前控件是否消费了这个事件,是否还允许Touch事件继续向上(父控件)传递。返回false,则向上传递给父控件。返回true,如果是子控件返回true,那么它的touch事件都在这里处理,父控件是处理不了,因为它收不到子控件传给他的touch,被子控件给拦截了。

PS:是否消费对处理是否有影响?有的,比如ACTION_MOVE或者ACTION_UP发生的前提是一定曾经发生了ACTION_DOWN,如果你没有消费ACTION_DOWN,那么系统会认为ACTION_DOWN没有发生过,所以ACTION_MOVE或者ACTION_UP就不能被捕获。

由此概念,我们大概能知道其区别了,onInterceptTouchEvent处理的事件是从父控件开始往子控件传的,直到有拦截或者到没有这个事件的view,然后就往回从子控件到父控件,从子控件到父控件则是由onTouchEvent来负责,两者的关系算是紧密相连的。由此我们也可以知道onInterceptTouchEvent是针对于有childview的ViewGroup才有的方法,onTouchEvent则是所有view都有的方法。

我们用一个小例子来说明这两者的工作方式:

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

这个简单的布局在手机上大概是这么个层级关系:

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

我们以最常见的down事件来说明

  1. down事件首先会传递到onInterceptTouchEvent()方法

  2. 如果该ViewGroup的onInterceptTouchEvent()在接收到down事件处理完成之后return false,那么后续的move, up等事件将继续会先传递给该ViewGroup,之后才和down事件一样传递给最终的目标view的onTouchEvent()处理。

  3. 如果该ViewGroup的onInterceptTouchEvent()在接收到down事件处理完成之后return true,那么后续的move, up等事件将不再传递给onInterceptTouchEvent(),而是和down事件一样传递给该ViewGroup的onTouchEvent()处理,注意,目标view将接收不到任何事件。

  4. 如果最终需要处理事件的view的onTouchEvent()返回了false,那么该事件将被传递至其上一层次的view的onTouchEvent()处理。

  5. 如果最终需要处理事件的view 的onTouchEvent()返回了true,那么后续事件将可以继续传递给该view的onTouchEvent()处理。

 我们来看看layoutview1的onInterceptTouchEvent若返回true的流程:

posted @ 2015-04-13 16:20  Simba.Chen  阅读(538)  评论(0编辑  收藏  举报