Android事件分发机制简单理解

参考链接https://blog.csdn.net/caifengyao/article/details/65437695?utm_medium=distribute.pc_relevant_t0.none-task-blog-BlogCommendFromMachineLearnPai2-1.channel_param&depth_1-utm_source=distribute.pc_relevant_t0.none-task-blog-BlogCommendFromMachineLearnPai2-1.channel_param 

View只能处理事件,不能往下分发事件。ViewGroup要先分发事件,再处理事件。

 

ViewGroup中

事件分为 dispatchTouchEvent(事件的分发),onInterceptTouchEvent(事件的拦截,返回true 代表拦截事件),onTouchEvent(事件的处理,返回true代表消费事件)

View中

事件分为dispatchTouchEvent(事件的分发),onTouchEvent(事件的处理)。

事件分发的顺序

Activity -> ViewGroup -> View。

从上层往下层分发(ViewGroup 即为上层,View 为下层),从下层往上层处理。

例子

class MyViewGroup(context: Context, attributeSet: AttributeSet): LinearLayout(context, attributeSet){
    override fun dispatchTouchEvent(event: MotionEvent?): Boolean {
        when (event?.action) {
            MotionEvent.ACTION_DOWN -> {
                Log.d("MyView.class", "ViewGroup_dispacth_DOWN")
            }
            MotionEvent.ACTION_MOVE -> {
                Log.d("MyView.class", "ViewGroup_dispacth_MOVE")
            }
            MotionEvent.ACTION_UP -> {
                Log.d("MyView.class", "ViewGroup_dispacth_UP")
            }
        }
        return super.dispatchTouchEvent(event)
    }

    override fun onInterceptTouchEvent(ev: MotionEvent?): Boolean {
        when (ev?.action) {
            MotionEvent.ACTION_DOWN -> {
                Log.d("MyView.class", "ViewGroup_intercept_DOWN")
            }
            MotionEvent.ACTION_MOVE -> {
                Log.d("MyView.class", "ViewGroup_intercept_MOVE")
            }
            MotionEvent.ACTION_UP -> {
                Log.d("MyView.class", "ViewGroup_intercept_UP")
            }
        }
        return super.onInterceptTouchEvent(ev)
    }

    override fun onTouchEvent(event: MotionEvent?): Boolean {
        when (event?.action) {
            MotionEvent.ACTION_DOWN -> {
                Log.d("MyView.class", "ViewGroup_onTouch_DOWN")
            }
            MotionEvent.ACTION_MOVE -> {
                Log.d("MyView.class", "ViewGroup_onTouch_MOVE")
            }
            MotionEvent.ACTION_UP -> {
                Log.d("MyView.class", "ViewGroup_onTouch_UP")
            }
        }
        return super.onTouchEvent(event)
    }
}
class MyView(context: Context, attributeSet: AttributeSet): View(context, attributeSet){
    override fun dispatchTouchEvent(event: MotionEvent?): Boolean {
        when (event?.action) {
            MotionEvent.ACTION_DOWN -> {
                Log.d("MyView.class", "View_dispacth_DOWN")
            }
            MotionEvent.ACTION_MOVE -> {
                Log.d("MyView.class", "View_dispacth_MOVE")
            }
            MotionEvent.ACTION_UP -> {
                Log.d("MyView.class", "View_dispacth_UP")
            }
        }
        return super.dispatchTouchEvent(event)
    }

    override fun onTouchEvent(event: MotionEvent?): Boolean {
        when (event?.action) {
            MotionEvent.ACTION_DOWN -> {
                Log.d("MyView.class", "View_onTouch_DOWN")
            }
            MotionEvent.ACTION_MOVE -> {
                Log.d("MyView.class", "View_onTouch_MOVE")
            }
            MotionEvent.ACTION_UP -> {
                Log.d("MyView.class", "View_onTouch_UP")
            }
        }
        return super.onTouchEvent(event)
    }
}

 

产生以下流程的事件均为点击custom_view

1. 对以上方法均不作处理,都返回super(调用父类方法,返回默认值)。这意味着我们既不拦截,也不消费。

 

2020-11-04 20:07:12.492 28679-28679/com.cl.eventtest D/MyView.class: Activity_dispatch_DOWN
2020-11-04 20:07:12.493 28679-28679/com.cl.eventtest D/MyView.class: ViewGroup_dispacth_DOWN
2020-11-04 20:07:12.493 28679-28679/com.cl.eventtest D/MyView.class: ViewGroup_intercept_DOWN
2020-11-04 20:07:12.493 28679-28679/com.cl.eventtest D/MyView.class: View_dispacth_DOWN
2020-11-04 20:07:12.495 28679-28679/com.cl.eventtest D/MyView.class: View_onTouch_DOWN
2020-11-04 20:07:12.496 28679-28679/com.cl.eventtest D/MyView.class: ViewGroup_onTouch_DOWN
2020-11-04 20:07:12.497 28679-28679/com.cl.eventtest D/MyView.class: Activity_onTouch_DOWN
2020-11-04 20:07:12.501 28679-28679/com.cl.eventtest D/MyView.class: Activity_dispatch_MOVE
2020-11-04 20:07:12.501 28679-28679/com.cl.eventtest D/MyView.class: Activity_onTouch_MOVE
2020-11-04 20:07:12.528 28679-28679/com.cl.eventtest D/MyView.class: Activity_dispatch_MOVE
2020-11-04 20:07:12.528 28679-28679/com.cl.eventtest D/MyView.class: Activity_onTouch_MOVE
2020-11-04 20:07:12.529 28679-28679/com.cl.eventtest D/MyView.class: Activity_dispatch_UP
2020-11-04 20:07:12.529 28679-28679/com.cl.eventtest D/MyView.class: Activity_onTouch_UP

 

 

如果对事件既不拦截,也不消费,当触发ACTION_DOWN的时候,事件会经过Activity——ViewGroup——View一层层的向下进行dispatchTouchEvent(分发)—onInterceptTouchEvent(拦截)调用。当到达最底层View后,开始触发消费操作,因为均不消费,ACTION_DOWN将由底层一层层向上冒,移交上层处理。当抵达最上层Activity后,说明下层均不消费,之后触发的ACTION_MOVE和ACTION_UP将不再向下层分发传递,直接交由Activity分发给自己进行处理。

 

2.将VIewGroup的onInterceptTouchEvent返回值改为true,即意味着ViewGroup拦截事件,但是并没有消费。

 

2020-11-04 20:14:33.591 3187-3187/com.cl.eventtest D/MyView.class: Activity_dispatch_DOWN
2020-11-04 20:14:33.592 3187-3187/com.cl.eventtest D/MyView.class: ViewGroup_dispacth_DOWN
2020-11-04 20:14:33.592 3187-3187/com.cl.eventtest D/MyView.class: ViewGroup_intercept_DOWN
2020-11-04 20:14:33.592 3187-3187/com.cl.eventtest D/MyView.class: ViewGroup_onTouch_DOWN
2020-11-04 20:14:33.593 3187-3187/com.cl.eventtest D/MyView.class: Activity_onTouch_DOWN
2020-11-04 20:14:33.622 3187-3187/com.cl.eventtest D/MyView.class: Activity_dispatch_MOVE
2020-11-04 20:14:33.622 3187-3187/com.cl.eventtest D/MyView.class: Activity_onTouch_MOVE
2020-11-04 20:14:33.630 3187-3187/com.cl.eventtest D/MyView.class: Activity_dispatch_UP
2020-11-04 20:14:33.630 3187-3187/com.cl.eventtest D/MyView.class: Activity_onTouch_UP

只是拦截事件,但是没有消费事件,那么 dispatchTouchEvent 不会继续往下调用,但是 onTouchEvent()还是会一层层往上调用。

3. ViewGroup的 onInterceptTouchEvent() 仍然返回super.onInterceptTouchEvent(),但是 onTouchEvent() 返回 true。即表示ViewGroup不拦截事件,但是消费事件。

2020-11-04 20:22:49.363 4290-4290/com.cl.eventtest D/MyView.class: Activity_dispatch_DOWN
2020-11-04 20:22:49.364 4290-4290/com.cl.eventtest D/MyView.class: ViewGroup_dispacth_DOWN
2020-11-04 20:22:49.364 4290-4290/com.cl.eventtest D/MyView.class: ViewGroup_intercept_DOWN
2020-11-04 20:22:49.364 4290-4290/com.cl.eventtest D/MyView.class: View_dispacth_DOWN
2020-11-04 20:22:49.365 4290-4290/com.cl.eventtest D/MyView.class: View_onTouch_DOWN
2020-11-04 20:22:49.366 4290-4290/com.cl.eventtest D/MyView.class: ViewGroup_onTouch_DOWN
2020-11-04 20:22:49.367 4290-4290/com.cl.eventtest D/MyView.class: Activity_dispatch_MOVE
2020-11-04 20:22:49.367 4290-4290/com.cl.eventtest D/MyView.class: ViewGroup_dispacth_MOVE
2020-11-04 20:22:49.367 4290-4290/com.cl.eventtest D/MyView.class: ViewGroup_onTouch_MOVE
2020-11-04 20:22:49.368 4290-4290/com.cl.eventtest D/MyView.class: Activity_dispatch_UP
2020-11-04 20:22:49.368 4290-4290/com.cl.eventtest D/MyView.class: ViewGroup_dispacth_UP
2020-11-04 20:22:49.368 4290-4290/com.cl.eventtest D/MyView.class: ViewGroup_onTouch_UP

 

此时因为没有拦截事件,Down事件仍然会下发到View ,但是事件在 ViewGroup 中消费了,所以不会向上传递给 Activity 处理。

同时之后的 MOVE 以及 UP 事件都不会向下分发到 View ,因为已经知道DOWN事件被ViewGroup消费了。

 

4. ViewGroup的 onInterceptTouchEvent() 和onTouchEvent() 的返回值均改为true,则意味着ViewGroup既拦截了事件,同时也消费了事件。

 

2020-11-04 20:31:00.920 6527-6527/com.cl.eventtest D/MyView.class: Activity_dispatch_DOWN
2020-11-04 20:31:00.925 6527-6527/com.cl.eventtest D/MyView.class: ViewGroup_dispacth_DOWN
2020-11-04 20:31:00.925 6527-6527/com.cl.eventtest D/MyView.class: ViewGroup_intercept_DOWN
2020-11-04 20:31:00.926 6527-6527/com.cl.eventtest D/MyView.class: ViewGroup_onTouch_DOWN
2020-11-04 20:31:00.938 6527-6527/com.cl.eventtest D/MyView.class: Activity_dispatch_MOVE
2020-11-04 20:31:00.938 6527-6527/com.cl.eventtest D/MyView.class: ViewGroup_dispacth_MOVE
2020-11-04 20:31:00.938 6527-6527/com.cl.eventtest D/MyView.class: ViewGroup_onTouch_MOVE
2020-11-04 20:31:00.959 6527-6527/com.cl.eventtest D/MyView.class: Activity_dispatch_MOVE
2020-11-04 20:31:00.959 6527-6527/com.cl.eventtest D/MyView.class: ViewGroup_dispacth_MOVE
2020-11-04 20:31:00.959 6527-6527/com.cl.eventtest D/MyView.class: ViewGroup_onTouch_MOVE
2020-11-04 20:31:00.959 6527-6527/com.cl.eventtest D/MyView.class: Activity_dispatch_UP
2020-11-04 20:31:00.959 6527-6527/com.cl.eventtest D/MyView.class: ViewGroup_dispacth_UP
2020-11-04 20:31:00.959 6527-6527/com.cl.eventtest D/MyView.class: ViewGroup_onTouch_UP

此时事件不会再向下至 View 分发,同时 也不会向上传递到 Activity 处理。

 

  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值