事件机制(1)--onInterceptTouchEvent和onTouchEvent调用时序

本文主要是介绍事件机制(1)--onInterceptTouchEvent和onTouchEvent调用时序,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

onInterceptTouchEvent()是ViewGroup的一个方法,目的是在系统向该ViewGroup及其各个childView触发onTouchEvent()之前对相关事件进行一次拦截,Android这么设计的想法也很好理解,由于ViewGroup会包含若干childView,因此需要能够统一监控各种touch事件的机会,因此纯粹的不能包含子view的控件是没有这个方法的,如LinearLayout就有,TextView就没有。 

onInterceptTouchEvent()使用也很简单,如果在ViewGroup里覆写了该方法,那么就可以对各种touch事件加以拦截。但是如何拦截,是否所有的touch事件都需要拦截则是比较复杂的,touch事件在onInterceptTouchEvent()和onTouchEvent以及各个childView间的传递机制完全取决于onInterceptTouchEvent()和onTouchEvent()的返回值。并且,针对down事件处理的返回值直接影响到后续move和up事件的接收和传递。 

关于返回值的问题,基本规则很清楚,如果return true,那么表示该方法消费了此次事件,如果return false,那么表示该方法并未处理完全,该事件仍然需要以某种方式传递下去继续等待处理。

SDK给出的说明如下:

· You will receive the down event here.

· The down event will be handled either by a child of this view group, or given to your own onTouchEvent() method to handle; this means you should implement onTouchEvent() to return true, so you will continue to see the rest of the gesture (instead of looking for a parent view to handle it). Also, by returning true from onTouchEvent(), you will not receive any following events in onInterceptTouchEvent() and all touch processing must happen in onTouchEvent() like normal.

· For as long as you return false from this function, each following event (up to and including the final up) will be delivered first here and then to the target's onTouchEvent().

· If you return true from here, you will not receive any following events: the target view will receive the same event but with the action ACTION_CANCEL, and all further events will be delivered to your onTouchEvent() method and no longer appear here.

 

由于onInterceptTouchEvent()的机制比较复杂,上面的说明写的也比较复杂,总结一下,基本的规则是:

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

2.       如果该ViewGroup的onInterceptTouchEvent()在接收到down事件处理完成之后return false,然后在将down事件传递给下一级

          View处理,而后续的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()处理。

6、    down事件最后被消费的地方,也是其他事件消费的地方,由于所有事件被消费的地方都是一致的,那么必须分析首要的down事

        件的流向就至为重要。如果最上面的容器没有在onTouchEvent中down中  return true,那么最后,会将这个事件继续上传给窗口,

        而窗口是一定会消费事件的,那么后续事件就直接在窗口被消费掉了,不会在传递给最上面容器了。

下面用一个简单的实验说明上述复杂的规则。视图自底向上共3层,其中LayoutView1和LayoutView2就是LinearLayout, MyTextView就是TextView:

对应的xml布局文件如下:

<?xmlversion="1.0"encoding="utf-8"?>

<com.touchstudy.LayoutView1xmlns:android="http://schemas.android.com/apk/res/android"

    android:orientation="vertical"

    android:layout_width="fill_parent"

    android:layout_height="fill_parent">

    <com.touchstudy.LayoutView2

        android:orientation="vertical"

        android:layout_width="fill_parent"

        android:layout_height="fill_parent"

        android:gravity="center">

       <com.touchstudy.MyTextView 

            android:layout_width="wrap_content"

            android:layout_height="wrap_content"

            android:id="@+id/tv"

            android:text="AB"

            android:textSize="40sp"

            android:textStyle="bold"

            android:background="#FFFFFF"

            android:textColor="#0000FF"/>

   </com.touchstudy.LayoutView2>

</com.touchstudy.LayoutView1>

 

下面看具体情况:

1.      onInterceptTouchEvent()处理down事件均返回falseonTouchEvent()处理事件均返回true

------------------------------------------------------------------------------------------------------------------------------

04-11 03:58:42.620: DEBUG/LayoutView1(614): onInterceptTouchEvent action:ACTION_DOWN

04-11 03:58:42.620: DEBUG/LayoutView2(614): onInterceptTouchEvent action:ACTION_DOWN

04-11 03:58:42.620: DEBUG/MyTextView(614): onTouchEvent action:ACTION_DOWN

04-11 03:58:42.800: DEBUG/LayoutView1(614): onInterceptTouchEvent action:ACTION_MOVE

04-11 03:58:42.800: DEBUG/LayoutView2(614): onInterceptTouchEvent action:ACTION_MOVE

04-11 03:58:42.800: DEBUG/MyTextView(614): onTouchEvent action:ACTION_MOVE

…… //省略过多的ACTION_MOVE

04-11 03:58:43.130: DEBUG/LayoutView1(614): onInterceptTouchEvent action:ACTION_UP

04-11 03:58:43.130: DEBUG/LayoutView2(614): onInterceptTouchEvent action:ACTION_UP

04-11 03:58:43.150: DEBUG/MyTextView(614): onTouchEvent action:ACTION_UP

------------------------------------------------------------------------------------------------------------------------------

这是最常见的情况,onInterceptTouchEvent并没有做任何改变事件传递时序的操作,效果上和没有覆写该方法是一样的。可以看到,各种事件的传递本身是自底向上的,次序是:LayoutView1->LayoutView2->MyTextView。注意,在onInterceptTouchEvent均返回false时,LayoutView1和LayoutView2的onTouchEvent并不会收到事件,而是最终传递给了MyTextView。

 

2.    LayoutView1onInterceptTouchEvent()处理down事件返回true

MyTextViewonTouchEvent()处理事件返回true

------------------------------------------------------------------------------------------------------------------------------

04-11 03:09:27.589: DEBUG/LayoutView1(446): onInterceptTouchEvent action:ACTION_DOWN

04-11 03:09:27.589: DEBUG/LayoutView1(446): onTouchEvent action:ACTION_DOWN

04-11 03:09:27.629: DEBUG/LayoutView1(446): onTouchEvent action:ACTION_MOVE

04-11 03:09:27.689: DEBUG/LayoutView1(446): onTouchEvent action:ACTION_MOVE

…… //省略过多的ACTION_MOVE

04-11 03:09:27.959: DEBUG/LayoutView1(446): onTouchEvent action:ACTION_UP

------------------------------------------------------------------------------------------------------------------------------

从Log可以看到,由于LayoutView1在拦截第一次down事件时return true,所以后续的事件(包括第一次的down)将由LayoutView1本身处理,事件不再传递下去。

 

3.       LayoutView1LayoutView2onInterceptTouchEvent()处理down事件返回false

MyTextViewonTouchEvent()处理事件返回false

LayoutView2onTouchEvent()处理事件返回true

----------------------------------------------------------------------------------------------------------------------------

04-11 09:50:21.147: DEBUG/LayoutView1(301): onInterceptTouchEvent action:ACTION_DOWN

04-11 09:50:21.147: DEBUG/LayoutView2(301): onInterceptTouchEvent action:ACTION_DOWN

04-11 09:50:21.147: DEBUG/MyTextView(301): onTouchEvent action:ACTION_DOWN

04-11 09:50:21.147: DEBUG/LayoutView2(301): onTouchEvent action:ACTION_DOWN

04-11 09:50:21.176: DEBUG/LayoutView1(301): onInterceptTouchEvent action:ACTION_MOVE

04-11 09:50:21.176: DEBUG/LayoutView2(301): onTouchEvent action:ACTION_MOVE

04-11 09:50:21.206: DEBUG/LayoutView1(301): onInterceptTouchEvent action:ACTION_MOVE

04-11 09:50:21.217: DEBUG/LayoutView2(301): onTouchEvent action:ACTION_MOVE

…… //省略过多的ACTION_MOVE

04-11 09:50:21.486: DEBUG/LayoutView1(301): onInterceptTouchEvent action:ACTION_UP

04-11 09:50:21.486: DEBUG/LayoutView2(301): onTouchEvent action:ACTION_UP

----------------------------------------------------------------------------------------------------------------------------

可以看到,由于MyTextView在onTouchEvent()中return false,down事件被传递给其父view,即LayoutView2的onTouchEvent()方法处理,由于在LayoutView2的onTouchEvent()中return true,所以down事件传递并没有上传到LayoutView1。注意,后续的move和up事件均被传递给LayoutView2的onTouchEvent()处理,而没有传递给MyTextView。

 

----------------------------------------------------------------------------------------------------------------

应大家的要求,我把源代码贴上,其实很简单,就是基础文件,主要是用来观察事件的传递。

 

主Activity: InterceptTouchStudyActivity.java:

 

public class InterceptTouchStudyActivityextends Activity {

    static final StringTAG = "ITSActivity";

    TextView tv;

   

    /** Called when the activity is first created. */

    @Override

    public void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        setContentView(R.layout.layers_touch_pass_test);

     }

 }

 


      LayoutView1.java:


      public class LayoutView1extends LinearLayout {

     private final String TAG = "LayoutView1";

       public LayoutView1(Context context, AttributeSet attrs) {

         super(context, attrs);

         Log.d(TAG,TAG);

     }

 

     @Override

     public boolean onInterceptTouchEvent(MotionEvent ev) {

         int action = ev.getAction();

         switch(action){

         case MotionEvent.ACTION_DOWN:

              Log.d(TAG,"onInterceptTouchEvent action:ACTION_DOWN");

//            return true;

              break;

         case MotionEvent.ACTION_MOVE:

              Log.d(TAG,"onInterceptTouchEvent action:ACTION_MOVE");

              break;

         case MotionEvent.ACTION_UP:

              Log.d(TAG,"onInterceptTouchEvent action:ACTION_UP");

              break;

         case MotionEvent.ACTION_CANCEL:

              Log.d(TAG,"onInterceptTouchEvent action:ACTION_CANCEL");

              break;

         }

        

         return false;

     }

 

     @Override

     public boolean onTouchEvent(MotionEvent ev) {

         int action = ev.getAction();

         switch(action){

         case MotionEvent.ACTION_DOWN:

              Log.d(TAG,"onTouchEvent action:ACTION_DOWN");

              break;

         case MotionEvent.ACTION_MOVE:

              Log.d(TAG,"onTouchEvent action:ACTION_MOVE");

              break;

         case MotionEvent.ACTION_UP:

              Log.d(TAG,"onTouchEvent action:ACTION_UP");

              break;

         case MotionEvent.ACTION_CANCEL:

              Log.d(TAG,"onTouchEvent action:ACTION_CANCEL");

              break;

         }

        

         return true;

     }

 

     @Override

     protected void onLayout(boolean changed,int l,int t,int r, int b) {

         // TODO Auto-generated method stub

         super.onLayout(changed, l, t, r, b);

     }

 

     @Override

     protected void onMeasure(int widthMeasureSpec,int heightMeasureSpec) {

         // TODO Auto-generated method stub

         super.onMeasure(widthMeasureSpec, heightMeasureSpec);

     }

}


LayoutView2.java:

 

public class LayoutView2extends LinearLayout {

    private final String TAG = "LayoutView2";

   

    public LayoutView2(Context context, AttributeSet attrs) {

       super(context, attrs);

       Log.d(TAG,TAG);

    }

 

    @Override

    public boolean onInterceptTouchEvent(MotionEvent ev) {

       int action = ev.getAction();

       switch(action){

       case MotionEvent.ACTION_DOWN:

           Log.d(TAG,"onInterceptTouchEvent action:ACTION_DOWN");

           break;

       case MotionEvent.ACTION_MOVE:

           Log.d(TAG,"onInterceptTouchEvent action:ACTION_MOVE");

           break;

       case MotionEvent.ACTION_UP:

           Log.d(TAG,"onInterceptTouchEvent action:ACTION_UP");

           break;

       case MotionEvent.ACTION_CANCEL:

           Log.d(TAG,"onInterceptTouchEvent action:ACTION_CANCEL");

           break;

       }

      

       return false;

    }

 

    @Override

    public boolean onTouchEvent(MotionEvent ev) {

       int action = ev.getAction();

       switch(action){

       case MotionEvent.ACTION_DOWN:

           Log.d(TAG,"onTouchEvent action:ACTION_DOWN");

           break;

       case MotionEvent.ACTION_MOVE:

           Log.d(TAG,"onTouchEvent action:ACTION_MOVE");

           break;

       case MotionEvent.ACTION_UP:

           Log.d(TAG,"onTouchEvent action:ACTION_UP");

           break;

       case MotionEvent.ACTION_CANCEL:

           Log.d(TAG,"onTouchEvent action:ACTION_CANCEL");

           break;

       }

      

       return true;

    } 

}


MyTextView.java:

public class MyTextViewextends TextView {

    private final String TAG = "MyTextView";

   

    public MyTextView(Context context, AttributeSet attrs) {

       super(context, attrs);

       Log.d(TAG,TAG);

    }

 

    @Override

    public boolean onTouchEvent(MotionEvent ev) {

       int action = ev.getAction();

       switch(action){

       case MotionEvent.ACTION_DOWN:

           Log.d(TAG,"onTouchEvent action:ACTION_DOWN");

           break;

       case MotionEvent.ACTION_MOVE:

           Log.d(TAG,"onTouchEvent action:ACTION_MOVE");

           break;

       case MotionEvent.ACTION_UP:

           Log.d(TAG,"onTouchEvent action:ACTION_UP");

           break;

       case MotionEvent.ACTION_CANCEL:

           Log.d(TAG,"onTouchEvent action:ACTION_CANCEL");

           break;

       }

      

       return false;

    }

   

    public void onClick(View v) {

       Log.d(TAG, "onClick");

    }

   

    public boolean onLongClick(View v) {

       Log.d(TAG, "onLongClick");

       return false;

    }

}

很直观!还有一疑问,如果所有onTouchEvent的down事件都return false,那么后续的move和up事件会如何传递呢?
Re: ddna2013-03-19 09:49发表[回复] [引用][举报]
回复arimood:欢迎你自己做个试验,这样理解的会比较直观。事件从下往上传,事件的消费从上向下传,消费者是上层优先级最高。
Re: lfdfhl2013-05-10 16:04发表[回复] [引用][举报]
回复ddna:楼主 你好 在你的博客里你提到 down事件首先会传递到onInterceptTouchEvent()方法 我觉得这个说法欠妥当.我看了些资料说的是先执行dispatchTouchEvent才再执行onInterceptTouchEvent,我的理解也是如此的.即先分发再由onInterceptTouchEvent决定是否拦截.于是写了个demo但是发现第一次根本就没有执行dispatchTouchEvent方法而是在某些时间会执行dispatchTouchEvent.请问:dispatchTouchEvent和onInterceptTouchEvent的执行顺序到底是怎么样的?谢谢你
Re: 夏安明2013-06-13 17:06发表[回复] [引用][举报]
回复lfdfhl:执行的顺序是先dispatchTouchEvent,然后onInterceptTouchEvent,但是dispatchTouchEvent的返回值必须是super.dispatchTouchEvent(ev)调用父类的方法,直接返回true和false都会阻止派发
Re: Black_smart2013-03-16 10:04发表[回复] [引用][举报]
回复arimood:这个问题问得很好。我来回答一下。
如果onTouchEvent的down事件都return false,那么在执行完down事件之后,move和up是都不会触发的。。。。。因为onTouchEvent并没有消费完down事件,而layoutview1上层又不能继续向上传递~
下面给出打印log:
03-16 02:03:43.018: D/LayoutView1(677): onInterceptTouchEvent action:ACTION_DOWN
03-16 02:03:43.018: D/LayoutView2(677): onInterceptTouchEvent action:ACTION_DOWN
03-16 02:03:43.018: D/MyTextView(677): onTouchEvent action:ACTION_DOWN
03-16 02:03:43.022: D/LayoutView2(677): onTouchEvent action:ACTION_DOWN
03-16 02:03:43.022: D/LayoutView1(677): onTouchEvent action:ACTION_DOWN
32楼 冰萧2013-01-10 22:53发表[回复] [引用][举报]
6. 默认状态下事件途经层层父视图会被传到最前的子视图childview的onTouchEvent()里面处理,如果这个childview不处理这些事件,或只处理部分事件,则对不处理的事件直接返回false就可以了。 第一次接收到的事件,因为最前的childview没有处理,onTouchEvent()返回了false,所以之后的事件传递过程中在经由这个childview的父视图时就不会再传给这个childview了。如果刚好这个childview的父视图的onTouchEvent()刚好返回true。则所有的事件都在该最前childview的父视图那里停止向childview的传递,所有事件都在childview的父视图的onTouchEvent()里面消费了。

7. 当一个父视图的onInterceptTouchEvent()对所有事件都返回false,但是onTouchEvent()返回true时,这种情况主要是想让所有能传递到这个父视图的事件优先让这个父视图的子视图childview处理,只有当它的childview的onTouchEvent()返回false不予处理时,这个childview的父视图才会进行处理。
31楼 冰萧2013-01-10 22:53发表[回复] [引用][举报]
1. Touch事件(ACTION_DOWN、ACTION_MOVE、ACTION_UP等)从父视图ViewGroup向各个childView发送,只有能包含其它childview的视图才有onInterceptTouchEvent()方法。

2. 事件由父视图向子视图发送,默认都是最前的view也即childview处理事件,所以默认状态下所有的事件都会经由父视图,具体就是经由层层父视图的onInterceptTouchEvent(),直到最前获得焦点的子视图childview,让childview处理事件,事件在这里被消费掉。

3. 父视图也好、子视图也好,真正处理事件的都是在onTouchEvent()方法里进行处理。

4. 因为默认状态下事件都是由层层父视图传递给最前的子视图childview处理,所以默认状态下childview之前的层层父视图都不拦截事件。

5. onInterceptTouchEvent()正是系统提供给具有父视图功能(能包含其它子视图的view)的控件能拦截事件的一个途经。如果这个父视图要拦截,就说明它要处理这些事件,所以onInterceptTouchEvent()返回true之后,以后的所有事件,在从它的层层父视图传递到此时就不再往后传递了。所有的事件都在这个父视图的onTouchEvent()里面被消费。
30楼 冰萧2013-01-10 22:04发表[回复] [引用][举报]
楼主的文章是我搜索相关主题,将Touch事件传递顺序解释的最好的文章。。。赞一个~!
Re: lfdfhl2013-05-10 16:04发表[回复] [引用][举报]
回复duanyipeng:回复ddna:你总结得很不错啊 在博客里提到 down事件首先会传递到onInterceptTouchEvent()方法 我觉得这个说法欠妥当.我看了些资料说的是先执行dispatchTouchEvent才再执行onInterceptTouchEvent,我的理解也是如此的.即先分发再由onInterceptTouchEvent决定是否拦截.于是写了个demo但是发现第一次根本就没有执行dispatchTouchEvent方法而是在某些时间会执行dispatchTouchEvent.请问:dispatchTouchEvent和onInterceptTouchEvent的执行顺序到底是怎么样的?谢谢你
Re: ddna2013-03-19 09:47发表[回复] [引用][举报]
回复duanyipeng:哈哈,欢迎大家共同切磋
29楼 yxz3291309522012-08-30 10:31发表[回复] [引用][举报]
写得好!
28楼 tgd1112012-08-14 02:26发表[回复] [引用][举报]
您好问两个问题:
1.一个viewgroup的onTouchEvent()最终consume了down事件以后,是不是只有这个viewgroup的父viewgroup的onInterceptTouchEvent()才能传递后续的move,up事件?
2,为什么当viewgroup的onInterceptTouchEvent()返回false后,子view最终消费了事件后,后续的move,up事件还需要经过onInterceptTouchEvent()的传递,而不是直接分发给最终的view呢?down事件就已经确定了,还会有变化吗?
27楼 zhangjinpeng4292012-04-01 13:20发表[回复] [引用][举报]
你好ddna! 有重要的事找你,请加我q 83627509,谢谢.
26楼 xraying2012-03-23 11:51发表[回复] [引用][举报]
楼主写的不错,顶一下!!
25楼 buyi0062012-03-22 16:43发表[回复] [引用][举报]
NB 说得很明白 代码应该自己去体验体验
24楼 烧伤的火柴2012-01-05 14:54发表[回复] [引用][举报]
受教了
23楼 zx198998912011-12-24 00:40发表[回复] [引用][举报]
受教了。。。
22楼 gold_hujian2011-12-22 16:45发表[回复] [引用][举报]
讲的很好,非常感谢.
21楼 Sibaozuan2011-09-21 21:09发表[回复] [引用][举报]
真让我醍壶罐顶,茅塞顿开。
20楼 reptest32011-08-25 18:57发表[回复] [引用][举报]
就ViewGroup的javadoc来说:
The down event will be handled either by a child of this view group, or given to your own onTouchEvent() method to handle; this means you should implement onTouchEvent() to return true, so you will continue to see the rest of the gesture (instead of looking for a parent view to handle it). Also, by returning true from onTouchEvent(), you will not receive any following events in onInterceptTouchEvent() and all touch processing must happen in onTouchEvent() like normal.

里面说了如果ViewGroup的onTouchEvent()返回true了,那之后的onInterceptTouchEvent应该接受不到down事件的后续move及up事件了,跟你文章里的情况1似乎有点矛盾啊,怎么还能收到呢,实际上我写程序的时候发现onInterceptTouchEvent截取了down事件之后,后续的move和up就只能交给onTouchEvent来处理了
Re: 无斑兔子2012-07-14 19:24发表[回复] [引用][举报]
回复reptest3:如果是子View的 onTouchEvent() 返回了true的话
在ViewGroup中的onInterceptTouchEvent()就能截取到move 和up了。

如果是当前ViewGroup中的onTouchEvent()最终消费了此次的事件,那不onInterceptTouchEvent()就不能截取到move和up事件了。
19楼 glzlaohuai2011-07-26 14:40发表[回复] [引用][举报]
我想写这样一个SlidingDrawer,SlidingDrawer的handle上边有组件,当点击组件时候会执行为组件set的on***Listener中的方法

是需要重写SlidingDrawer中的onInterceptTouchEvent呢,还是handle中的onInterceptTouchEvent()呢~?
18楼 fzclzhai2011-07-13 14:53发表[回复] [引用][举报]
写的真好,谢谢!
17楼 panxq08092011-07-11 14:24发表[回复] [引用][举报]
楼主讲的很透彻,非常感谢。
16楼 zzp162011-07-02 10:21发表[回复] [引用][举报]
写的非常好,你的学习精神我收下了,文章也收藏了。谢谢分享··
我就是被返回值及move、up事件没有处理而困扰了。谢谢你的文章
15楼 chensenym2011-04-22 22:37发表[回复] [引用][举报]
很好的一篇文章!!!
14楼 tance1020042011-04-20 12:22发表[回复] [引用][举报]
分析的很透彻.架构上明亮了很多.
13楼 zyxnum2011-03-25 11:44发表[回复] [引用][举报]
学习了[e03]
12楼 mlianghua2011-03-04 11:07发表[回复] [引用][举报]
悲剧,不能发表超过150个字.............
11楼 mlianghua2011-03-04 11:07发表[回复] [引用][举报]
楼主,写的不是很清楚,我来具体写一下,这样更清晰,希望别人改进:总结一下,基本的规则是:
1. down事件首先会传递到父View(ViewGroup)的onInterceptTouchEvent()方法
10楼 mlianghua2011-03-04 10:25发表[回复] [引用][举报]
不错,很好,总结一句话,先父View捕捉到Touch, 通过onInterceptTouchEvent(),决定是否传递给子Touch, 不下传,就处理掉。
9楼 fdasfdsaf2010-12-28 14:29发表[回复] [引用][举报]
已经明白了,thanks...
8楼 fdasfdsaf2010-12-28 13:17发表[回复] [引用][举报]
3. LayoutView1,LayoutView2的onInterceptTouchEvent()处理down事件返回false,

MyTextView的onTouchEvent()处理事件返回false

LayoutView2的onTouchEvent()处理事件返回true

这种情况有点疑问:LayoutView1,LayoutView2的onInterceptTouchEvent()处理down事件返回false,说明都不对down 事件进行拦截,MyTextView的onTouchEvent()处理事件返回false ,又将 down 事件抛给了 LayoutView2 , 尽管LayoutView2 的onTouchEvent 事件返回true,可是 它的InterceptToucheEvent 事件根本就没拦截 down 事件,怎么会去处理呢 ?有点不明白,麻烦指点下... QQ:1033329191
7楼 finalsmile2010-12-09 11:54发表[回复] [引用][举报]
&quot;如果该ViewGroup的onInterceptTouchEvent()在接收到down事件处理完成之后return false,那么后续的move, up等事件将继续会先传递给该ViewGroup,之后才和down事件一样传递给最终的目标view的onTouchEvent()处理。&quot;

onInterceptTouchEvent()在接收到down事件处理完成之后return false,down事件是不会传递给onTouchEvent的
Re: ddna2010-12-10 06:32发表[回复] [引用][举报]
回复 finalsmile:说的很对~ 我那句话的意思是在下一次Touch事件被触发时,由于前次ViewGroup的onInterceptTouchEvent()针对down事件返回的是false,那么此次新的事件将继续先发给onInterceptTouchEvent()处理。“后续的move, up等事件”指的是下一次的事件触发,不是本次的继续调用。 呵呵,欢迎交流~ [e03]

这篇关于事件机制(1)--onInterceptTouchEvent和onTouchEvent调用时序的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/346095

相关文章

JVM 的类初始化机制

前言 当你在 Java 程序中new对象时,有没有考虑过 JVM 是如何把静态的字节码(byte code)转化为运行时对象的呢,这个问题看似简单,但清楚的同学相信也不会太多,这篇文章首先介绍 JVM 类初始化的机制,然后给出几个易出错的实例来分析,帮助大家更好理解这个知识点。 JVM 将字节码转化为运行时对象分为三个阶段,分别是:loading 、Linking、initialization

禁止平板,iPad长按弹出默认菜单事件

通过监控按下抬起时间差来禁止弹出事件,把以下代码写在要禁止的页面的页面加载事件里面即可     var date;document.addEventListener('touchstart', event => {date = new Date().getTime();});document.addEventListener('touchend', event => {if (new

如何在页面调用utility bar并传递参数至lwc组件

1.在app的utility item中添加lwc组件: 2.调用utility bar api的方式有两种: 方法一,通过lwc调用: import {LightningElement,api ,wire } from 'lwc';import { publish, MessageContext } from 'lightning/messageService';import Ca

Java ArrayList扩容机制 (源码解读)

结论:初始长度为10,若所需长度小于1.5倍原长度,则按照1.5倍扩容。若不够用则按照所需长度扩容。 一. 明确类内部重要变量含义         1:数组默认长度         2:这是一个共享的空数组实例,用于明确创建长度为0时的ArrayList ,比如通过 new ArrayList<>(0),ArrayList 内部的数组 elementData 会指向这个 EMPTY_EL

【编程底层思考】垃圾收集机制,GC算法,垃圾收集器类型概述

Java的垃圾收集(Garbage Collection,GC)机制是Java语言的一大特色,它负责自动管理内存的回收,释放不再使用的对象所占用的内存。以下是对Java垃圾收集机制的详细介绍: 一、垃圾收集机制概述: 对象存活判断:垃圾收集器定期检查堆内存中的对象,判断哪些对象是“垃圾”,即不再被任何引用链直接或间接引用的对象。内存回收:将判断为垃圾的对象占用的内存进行回收,以便重新使用。

【Tools】大模型中的自注意力机制

摇来摇去摇碎点点的金黄 伸手牵来一片梦的霞光 南方的小巷推开多情的门窗 年轻和我们歌唱 摇来摇去摇着温柔的阳光 轻轻托起一件梦的衣裳 古老的都市每天都改变模样                      🎵 方芳《摇太阳》 自注意力机制(Self-Attention)是一种在Transformer等大模型中经常使用的注意力机制。该机制通过对输入序列中的每个元素计算与其他元素之间的相似性,

如何通俗理解注意力机制?

1、注意力机制(Attention Mechanism)是机器学习和深度学习中一种模拟人类注意力的方法,用于提高模型在处理大量信息时的效率和效果。通俗地理解,它就像是在一堆信息中找到最重要的部分,把注意力集中在这些关键点上,从而更好地完成任务。以下是几个简单的比喻来帮助理解注意力机制: 2、寻找重点:想象一下,你在阅读一篇文章的时候,有些段落特别重要,你会特别注意这些段落,反复阅读,而对其他部分

【Tools】大模型中的注意力机制

摇来摇去摇碎点点的金黄 伸手牵来一片梦的霞光 南方的小巷推开多情的门窗 年轻和我们歌唱 摇来摇去摇着温柔的阳光 轻轻托起一件梦的衣裳 古老的都市每天都改变模样                      🎵 方芳《摇太阳》 在大模型中,注意力机制是一种重要的技术,它被广泛应用于自然语言处理领域,特别是在机器翻译和语言模型中。 注意力机制的基本思想是通过计算输入序列中各个位置的权重,以确

【LabVIEW学习篇 - 21】:DLL与API的调用

文章目录 DLL与API调用DLLAPIDLL的调用 DLL与API调用 LabVIEW虽然已经足够强大,但不同的语言在不同领域都有着自己的优势,为了强强联合,LabVIEW提供了强大的外部程序接口能力,包括DLL、CIN(C语言接口)、ActiveX、.NET、MATLAB等等。通过DLL可以使用户很方便地调用C、C++、C#、VB等编程语言写的程序以及windows自带的大

FreeRTOS内部机制学习03(事件组内部机制)

文章目录 事件组使用的场景事件组的核心以及Set事件API做的事情事件组的特殊之处事件组为什么不关闭中断xEventGroupSetBitsFromISR内部是怎么做的? 事件组使用的场景 学校组织秋游,组长在等待: 张三:我到了 李四:我到了 王五:我到了 组长说:好,大家都到齐了,出发! 秋游回来第二天就要提交一篇心得报告,组长在焦急等待:张三、李四、王五谁先写好就交谁的