Android 事件分发机制原理总结

事件定义

当手指接触屏幕时,产生触摸行为(Touch事件),有4种事件类型:

  • MotionEvent.ACTION_DOWN 手指刚接触屏幕
  • MotionEvent.ACTION_UP 手指从屏幕松开
  • MotionEvent.ACTION_MOVE 手指在屏幕上滑动
  • MotionEvent.ACTION_CANCEL 非人为因素取消

事件分发对象

Activity : 控制生命周期 & 处理事件
ViewGroup : 一组View的集合
View : 所有UI组件的基类

主要方法

dispatchTouchEvent(MotionEvent ev) // 用来处理
onInterceptTouchEvent(MotionEvent ev) // 判断是否要拦截事件(只存在ViewGroup中)
onTouchEvent(MotionEvent ev) // 处理事件

Activity的事件分发

public boolean dispatchTouchEvent(MotionEvent ev){
    if(ev.getAction() == MotionEvent.ACTION_DOWN){
        // 空方法,子类可以重写
        onUserInteraction();
    }
    // getWindow 是 PhoneWindow对象
    // 最终调用 ViewGroup.dispacthTouchEvent()
    if(getWindow().superDispatchTouchEvent()){
        return true;
    }
    return onTouchEvent();
}

ViewGroup的事件分发伪代码

public boolean dispatchTouchEvent(MotionEvent ev){
    boolean consume = false ;
    if(onInterceptTouchEvent(ev)){
        // 拦截则调用自身的onTouchEvent()
        consume = onTouchEvent(ev);
    }else{
        // 不拦截,将事件风发给子View
        consume = child.dispatchTouchEvent(ev);
    }
    return consume ;
}

事件分发结论

  1. 正常情况下,一个事件序列只能被一个View拦截并且消耗
  2. 某个View一旦进行拦截,那么这个事件序列都将由它的onTouchEvent处理,
    并且它的onInterceptTouchEvent不会再调用。
  3. 某个View一旦开始处理事件,如果它不消耗ACTION_DOWN事件(onTouchEvent返回false),
    那么同一系列中的其他事件都不会再交给它处理。并且重新交由它的父元素处理。
  4. 事件的传递过程是由外向内的,事件总是先传递给父元素,再由父元素分发给子View,
    通过requestDisallowInterceptTouchEvent方法可以在子View中干预父元素的事件分发过程,ACTION_DOWN事件除外。
  5. ViewGroup默认不拦截事件,onInterceptTouchEvent默认返回false。
    View没有onInterceptTouchEvent方法,一旦有事件传递给它,那么它的onTouchEvent方法就会被调用。
  6. View的onTouchEvent默认消耗事件(返回true),除非它是不可点击的(clickable和longClickable同时为false)。
    View的longClickable默认都为false,clickable则不一定:Button的clickable默认为true,TextView的clickable默认为false。
    View的enable属性不影响onTouchEvent的默认返回值。
  7. onClick会响应的前提是View可点击,并且收到了ACTION_DOWN和ACTION_UP事件,
    并且受长按事件的影响,当长按事件返回true时,onClick不会响应。
  8. onLongClick在ACTION_DOWN事件里判断是否进行响应,想执行长按事件,View必须是longClickable,并且设置了OnLongClickListener。
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值