欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

View的事件分发机制

程序员文章站 2022-05-14 15:26:51
...

事件分发:即对MotionEvent事件的分发过程,当产生一个MotionEvent之后,系统需要把它传递到一个具体的View的过程。

相关方法

  • dispatchTouchEvent方法:用来进行事件的分发,如果事件传递到当前的View,此方法被调用
    返回结果:代表是否消费该事件
    受当前View的onTouchEvent和下级View的dispatchTouchEvent方法的影响

  • onInterceptTouchEvent方法:在dispatchTouchEvent中调用,用来判断是否拦截事件,如果当前View拦截了某个时间,则在统一序列事件当中,此方法不会再被调用
    返回结果表示是否拦截当前事件

  • onTouchEvent方法:在dispatchTouchEvent方法中调用,用来处理点击事件,如果不消费当前事件,则当前VIew无法再次接收到事件。
    返回结果:表示是否消费当前View。

以下是在网上看到的一张事件分发图(谢谢出处):View的事件分发机制

设置监听

  • 如果设置OnTouchListener,那么onTouch会被调用
    onTouch返回false,则onTouchEvent会被调用;
    返回true,则onTouchEvent不会调用。
  • 在onTouchEvent中,如果设置了OnClickListener,则onClick会被调用

事件大方面的传递: Activity->Window->View ,如果都没有处理,最终交由Activity处理。

结论(根据《Android开发艺术塔索》做的笔记)

  • 同一事件序列是指从手指接触屏幕那一刻起,到手指离开屏幕那一刻结束:DOWN->MOVE->MOVE->…->UP
  • 正常情况下,一个事件序列只能够被一个View拦截且消耗
  • 某个View一旦决定拦截,那么这一事件序列都只能由它来处理,并且它的onInterceptTouchEvent不会再被调用
  • 某个View一旦开始处理事件,如果它不消耗ACTION_DOWN事件(在onTouchEvent返回false),那么同一事件序列的其他事件将不会再交给它处理,而是给它的父View处理,即父View的OnTouchEvent会被调用
  • 如果View不消耗除ACTION_DOWN事件,那么这个点击事件会被消失,最终这些消失的事件会传给Activity处理
  • ViewGroup默认不拦截任何事件,查看源码可知它的onInterceptTouchEvent默认返回false
  • View没有onInterceptTouchEvent方法,一旦事件传递给它,它的onTouchEvent会被调用
  • View的onTouchEvent方法默认是消耗事件的,即返回true,除非它是不可点击的(clickable&longClickable=false)
  • View的enable属性不影响onTouchEvent默认返回的值,只要该View的clickable/longClickable=true,那么它的onTouchEvent就返回true
  • onClick会发生的前提是View是可点击的,并且收到DOWN和UP的事件
  • 事件传递:
    从外到内
    从父到子
    子View可以通过requestDisallowInterceptTouchEvent方法可以干预父元素的事件分发过程,ACTION_DOWN除外

    以上是个人对View事件分发机制的学习的笔记,如有错误,请多多指出。