Android中的事件分发总结

Android中的事件分发机制测试:

 

对于布局:

 

 

其布局为 

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"

    xmlns:tools="http://schemas.android.com/tools"

    android:layout_width="match_parent"

    android:layout_height="match_parent"

    tools:context="com.example.test_event_dispatch_oninterccept_ontouch.MainActivity">

   

    <com.example.test_event_dispatch_oninterccept_ontouch.ViewgroupFather

        android:layout_width="match_parent"

        android:layout_height="match_parent"

        android:background="@android:color/holo_blue_light"

        >

        <com.example.test_event_dispatch_oninterccept_ontouch.ViewGroupChild

            android:layout_width="200dp"

            android:layout_height="200dp"

            android:background="@android:color/holo_red_light"

            >

            <com.example.test_event_dispatch_oninterccept_ontouch.MyTextView android:layout_width="wrap_content"

                android:layout_height="wrap_content"

                android:layout_gravity="center_vertical"

                android:text="事件分发测试"

                android:background="@android:color/holo_orange_dark">

               

            </com.example.test_event_dispatch_oninterccept_ontouch.MyTextView>

          

        </com.example.test_event_dispatch_oninterccept_ontouch.ViewGroupChild>

       

       

       

    </com.example.test_event_dispatch_oninterccept_ontouch.ViewgroupFather>

   

</RelativeLayout>

 

 

测试一:

控件名称       dispatch       intercept         touch  

Ativity       super                            super

Father        super          super              super

Child         super          super              super

MyTextView    super                            super

 

测试结果:

 

 

 

 

 

总结:

当dispatch返回值为super的时候:

当dispatch返回值为super时,则自动将事件分发给当前view的intercept方法,以确定是否拦截事件;如果该dispatch所在的控件为最小单元时,则将事件传递给touch;如果该dispatch所在为Activity时,则将事件分发其下最外层布局,由该布局进行事件分发。

当dispatch返回值为true的时候:

事件将会在当前View的dispatch方法中被消费,不在向下级传递。

当dispatch返回值为false的时候:

如果该dispatch方法接收的事件是由外层容器(父级容器)传进来的,则将该事件交给外层容器的touch方法处理。

如果该dispatch方法在Acticity中,则直接由activity中的touch方法消费该事件。

 

当intercept返回值为super的时候:

事件将不会被拦截,而且经过该intercept方法传递到子View或子ViewGroup的dispatch方法上,与该dispatch方法进行事件分发。

当intercept返回值为true的时候:

事件将被拦截,而后交由当前ViewGroup的touch事件进行消费。

当intercept返回值为false的时候:

事件将不会被拦截,而且该事件将由该方法传递给子view或子Viewgroup的dispatch方法从新分发。

 

 

当touch返回值为super的时候:

事件将会由该touch所在容器向父级容器的touch传递,若父级容器也返回super或者false,则继续向父级容器传递直至传递到Acticity的touch方法中。

当touch返回值为true的时候:

事件将在该touch方法中被消费。

当touch返回值为false的时候:

与返回super相同。

 

 

 

事件分发调用的方法可以分为两步

第一步为试探性分发,例如上面的demo,假如在child的dispatch中返回true,则其分发可以理解为:从acticity试探性的将事件正常分发到father,从father正常分发到child中的dispatch中,发现dispatch返回值为true;

则Android事件分发机制可以确定事件分发到此处为止,于是开始正式分发事件,从activity的dispatch开始,逐级分发一直分发到child的dispatch方法中。

对于touch方法而言,如果在试探性事件分发中,事件没有被消费掉,则会逐级向父级touch方法传递,直至传递到acticity的touch方法为止,此时,事件分发机制认为,该事件将会由acticity的touch事件消费,于是,直接将事件分发给acticity的touch方法,则会出现以下结果:

 

 

 

举例:

测试二:

控件名称       dispatch       intercept         touch  

Ativity       super                             super

Father        super          super              super

Child         super          super              true

MyTextView    super                            super

结果:


结果解释:

当点击事件发生后,activity的dispatch方法将开始分发事件,由于该方法的返回值是super,所以原本应该会被传到当前dispatch所在位置的intercept方法中进行判断是否拦截,但是由于当前dispatch所在的位置是acticity,没有intercepter方法,所以,默认事件向下级传递。其过程:(MainActicitydispatchTouchEvent—>FatherdispatchTouchEvent),该过程后,于是事件从acticity中被传递到了father的dispatch方法中。由于father的dispatch方法的返回值也是super。则事件被传递到intercepter中判断是否需要拦截,而该intercepter的返回值也是super,默认表示不拦截,于是,事件将继续想下级传递。其过程:FatherdispatchTouchEvent—>FatheronInterceptTouchEvent—>ChilddispatchTouchEvent,该过程后,事件被传递到了Child的dispatchTouchEvent中,由于Child的dispatchTouchEvent方法返回值也是super,则该事件被交由Child的onInterceptTouchEvent方法判断是否拦截,该方法返回值依旧为super,表示不拦截,则事假继续想下级传递到MyTextView的dispatchTouchEvent方法中,其过程:ChilddispatchTouchEvent—>ChildonInterceptTouchEvent—>MyTextViewdispatchTouchEvent,该过程后,事件被传递到了MyTextView的dispatchTouchEvent中,由于MyTextView的dispatchTouchEvent返回值是super,原本该将该事件分发该onInterceptTouchEvent方法进行判断是否拦截,但是由于MyTextView已经是最小单元,不在有下级,于是该事件被分发给了最小单元的onTouchEvent方法。由于MyTextView的onTouchEvent方法返回值为super,表示向上级传递,则该事件由当前onTouchEvent方法传递给了父级Child的onTouchEvent方法,其过程:MyTextViewdispatchTouchEvent—>MyTextViewonTouchEvent—>ChildonTouchEvent,该过程后,事件被传递到了Child的onTouchEvent方法中,由于该方法的返回值为true,表示事件在此方法中被消费掉,于是,整个试探性事件分发完成。事件的试探性分发完成之后,将进行事件分发,采用的是事件的逐级分发,事件由Activity的dispatchTouchEvent方法开始分发到Father的dispatchTouchEvent,由于Child不在当前级,则在Father层使用onInterceptTouchEvent来判断事件是否拦截,确认不拦截后,事件从Father的onInterceptTouchEvent下发到Child的dispatchTouchEvent中,由于Child中的onTouchEvent方法就在当前层,不用再判是否进行事件拦截,于是,Child的dispatchTouchEvent方法直接将事件发给Child的onTouchEvent方法,其过程:(ActivitydispatchTouchEvent—>FatherdispatchTouchEvent—>FatheronInterceptTouchEvent—>ChilddispatchTouchEvent—>ChildonTouchEvent至此,整个事件分发结束。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值