Android的时间分发机制 完整解析

31 篇文章 0 订阅

在Android的触摸点击等事件中我们经常需要用到时间分发机制,看了很多朋友写的博客,感觉不是很明朗,综合多家的精粹用通俗的描述全面的介绍下事件分发机制。


1。首先来一张全局图
在这里插入图片描述

1代表我们的activity
2代表我们的viewgroup 也就是我们经常说的容器
3 就是最顶层的view了 比偶如说 textview imageview等

先简单的介绍下,稍后再代码分析

当点击最顶层的view的时候
down事件经过: activity的分发机制函数 dispatchTouchEvent 当返回true或者false的时候事件就在分发中就会被消费,不会传到上一层,也不会执行activity的 onTouchEvent

/**
     * 事件的分发
     * 分发事件的方法。当接收到事件时,通过调用此方法来决定是否分发。
     * @param ev
     * @return
     *  true: 事件不再进行分发且已经在自身事件的分发中被消费
     *  false: 也不对事件进行分发。
     *  也就是说该方法不论是返回true还是返回false都不会对事件进行分发,
     *
     *  只有当返回系统默认super.dispatchTouchEvent(ev)时,才会将事件分发给本层
     *  的拦截事件onInterceptTouchEvent(MotionEvent ev)去处理,如果没有onInterceptTouchEvent(MotionEvent ev)方法
     *  则直接分发给子View中的onInterceptTouchEvent(MotionEvent ev)方法处理
     *
     */
    @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
        if(ev.getAction() == MotionEvent.ACTION_DOWN){
            Log.d("data","[LinearLayout]--dispatchTouchEvent:"+ev.getAction()+"     "+super.dispatchTouchEvent(ev));
        }
        return super.dispatchTouchEvent(ev);
    }
	/*log日志
    *EventActivity: dispatchTouchEvent=====ACTION_DOWN
    *EventActivity: dispatchTouchEvent=====ACTION_UP
    */

activity的 dispatchTouchEvent返回super.dispatchTouchEvent(ev)的时候事件往下传递进入viewgroup的分发机制中,
如果viewgroupdispatchTouchEvent返回true/false的时候,事件不会被往下分发,而是回传到activityonTouchEvent去消费事件,在activity中的onTouchEvent执行完事件后如果返回true表示消费了这个事件,传递到此结束,返回false表示不处理事件,继续分发,此时事件就丢失了

如果viewgroupdispatchTouchEvent返回super.dispatchTouchEvent(ev);的时候,down事件就会继续继续向上传递,到达View顶层的dispatchTouchEvent,如果View的dispatchTouchEvent返回true/false的时候,事件会传递给viewgrouponTouchEvent去消费事件,只有返回super.dispatchTouchEvent(ev);才会调用本层的onTouchEvent,如果本层onTouchEvent返回true,事件到此结束,相当于消耗了事件。如果返回false的话,接下来的move和up事件将不会分配给View,而是直接在viewgrouponTouchEvent去消费事件。

ViewGroup特有的时间拦截 onInterceptTouchEvent

    /**
     * 事件的拦截
     * 拦截事件方法,该方法只有在布局或者ViewGroup中才会有。通过调用该方法来决定是否对事件
     * 进行拦截。
     * @param ev
     * @return
     *  true:进行拦截,将事件进行分发onTouchEvent方法处理
     *  false:不对事件进行拦截,传递给下一级处理
     */
    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        if(ev.getAction() ==MotionEvent.ACTION_DOWN){
            Log.d("data","[LinearLayout]--onInterceptTouchEvent:"+ev.getAction()+"     "+super.onInterceptTouchEvent(ev));
        }
        return super.onInterceptTouchEvent(ev);
    }

事件处理函数

/**
     * 事件的处理
     * 处理事件。当对事件进行了拦截时,将会调用onTouchEvent方法对事件进行处理。
     *
     * @param ev
     * @return
     *  true:表示该View能处理该事件,事件将终止向上传递(传递给其父View)
     *  false:不能处理,则把事件传递给其父View的onTouchEvent方法来处理
     */
    @Override
    public boolean onTouchEvent(MotionEvent ev) {
        if(ev.getAction() ==MotionEvent.ACTION_DOWN){
            Log.d("data","[LinearLayout]--onTouchEvent:"+ev.getAction()+"     "+super.onTouchEvent(ev));
        }
        return super.onTouchEvent(ev);
    }
    //注意:onTouchEvent事件消费函数一旦返回false 后面的鼠标UP 和 MOVE 就不会在这里执行了,但是下一次down事件能获取到

Android中的事件在表现形式上有很多,如onTouch、onClick和onLongClick等,在具体微观上的表现形式有action_down、action_move和action_up等。但是不管是哪种表现形式,都是基于事件的传递。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值