View的事件分发机制

  • 事件分发机制:事件传递给某View,调用该View的dispatchTouchEvent方法,在该方法内部调用onInterceptTouchEvent方法,返回true,表示拦截,调用onTouchEvent方法,返回true,表示消耗该事件,返回false表示不处理该事件,交给父View的onTouchEvent方法处理;返回false,表示不拦截,将事件继续向下传递给子View,调用子View的dispatchTouchEvent方法。
  • 如果View拦截了某事件,则在同一事件序列中,拦截方法不会被再次调用;如果View不消耗某一事件,则同一事件序列中,当前View无法再次接收该事件。
  • 如果View不消耗除ACTION_DOWN以外的事件,那么这个点击事件会消失,此时父元素的onTouchEvent并不会被调用,最终这些消失的事件会传递给Activity处理。
  • 同一事件序列:从手指接触屏幕的那一刻起,到手指离开屏幕的那一刻止,这个过程中所产生的一系列事件。
  • onTouchListener的onTouch方法返回值为false时,onTouchEvent方法被调用,为true时,onTouchEvent方法不会被调用;在onTouchEvent方法中,如果当前View设置有OnClickListener,那么onClick方法会被调用,三者优先级OnTouchListener>onTouchEvent>onClickListener
  • 事件传递过程:Activity–>Window–>View。可以通过requestDisallowInterceptTouchEvent在子元素中干预父元素的事件分发过程。
  • 正常情况下,一个事件序列只能被一个View拦截且消耗,但是可以通过onTouchEvent强行传递给其它View处理。
  • ViewGroup默认不拦截任何事件
  • View的onTouchEvent默认都会消耗事件(返回true),除非它是不可点击的(clickable和longClickable同时为false)。View的enable属性不影响onTouchEvent的默认返回值。
    滑动冲突的解决
    1.外部拦截法
    外部拦截法需要重写父容器的onInterceptTouchEvent方法,在ACTION_DOWN中必须返回false,即不拦截ACTION_DOWN事件,因为一旦父容器拦截了ACTION_DOWN,那么后续的ACTION_MOVE和ACTION_UP事件都会直接交由父容器处理,这个时候事件没法传给子元素了;ACTION_MOVE事件根据需要来决定是否拦截;ACTION_UP事件必须返回false,因为一旦父容器开始拦截事件,即便ACTION_UP返回false,ACTION_UP作为最后一个事件也可以传递到父容器,但如果父容器返回了true,子元素就无法接收到ACTION_UP事件,就无法触发onClick事件。
    2.内部拦截法
    父容器不拦截任何事件,所有事件都传递给子元素,如果子元素需要此事件就直接消耗掉,否则交给父容器进行处理。需要在dipatchTouchEvent方法中配合requestDisallowInterceptTouchEvent方法使用。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值