《android高级进阶》学习笔记(一)
1.android触摸事件传递机制
1.1 在android系统中,拥有事件传递处理能力的类有以下三种:
- Activity:拥有dispatchTouchEvent和onTouchEvent两个方法;
- View:拥有dispatchTouchEvent、onInterceptTouchEvent和onTouchEvent三个方法;
- ViewGroup:拥有dispatchTouchEvent和onTouchEvent两个方法。
1.2触摸事件的类型
事件的类型主要有三种:
- ACTION_DOWN:按下操作,一个按下操作标志着一次触摸事件的开始;
- ACTION_MOVE:按压屏幕后,在松开之前,如果移动距离超过一定的阈值,判定为ACTION_MOVE操作,一般情况下,手指的轻微移动都会触发一系列的移动事件;
ACTION_UP:手指离开屏幕的操作,一次抬起操作标志着一次触摸事件的结束。
一次触摸事件中,ACTION_DOWN和ACTION_UP两个事件类型是必需的,ACTION_MOVE视情况而定。
1.3事件传递的三个阶段
一次完整的事件传递主要包括三个阶段,分别是事件的分发、拦截和消费。
- 分发(dispatch):事件的分发对应着dispatchTouchEvent方法,在android系统中,所有的触摸事件都是通过此方法来分发的,方法原型如下:
public boolean dispatchTouchEvent(MotionEvent ev)
在此方法中,根据当前视图的具体实现逻辑来决定是直接消费此事件还是将此事件分发给子视图处理,返回值为true,表示事件被当前视图消费掉,不再分发事件;返回值为super.dispatchTouchEvent 表示分发事件给子视图。如果当前视图是ViewGroup及其子类,则会调用onInterceptTouchEvent方法是否拦截该事件。
- 拦截(intercept):事件的拦截对应onInterceptTouchEvent方法,此方法只在ViewGroup及其子类中才存在,在View和Activity中是不存在的。方法的原型如下:
public boolean onInterceptTouchEvent(MotionEvent ev)
此方法通过返回的布尔值来决定是否拦截对应的事件,返回true表示拦截此事件,不继续分发给子视图,同时交给自身的onTouchEvent方法进行消费;返回false或者super.onInterceptTouchEvent 表示不对事件进行拦截,继续传递给子视图。
- 消费(Consume):事件的消费对应着onTouchEvent方法,方法原型如下
public boolean onTouchEvent(MotionEvent event)
此方法返回值为true 表示当前视图可以处理对应的事件,事件将不会向上传递给父视图;返回值为false 表示当前视图不处理该事件,事件会被传递给父视图的onTouchEvent方法进行处理。
1.4View的事件传递机制
以View的ACTION_DOWN事件为例,流程图如下:
从上面流程图总结:
- 触摸事件的传递流程是从dispatchTouchEvent开始的,如果默认返回父类的同名函数,则事件会依照嵌套层次从外层向内层传递,达到最内层的View时,由View的onTouchEvent方法处理,g该方法若消费此事件,则返回true,否则返回false,此时事件会重新向外层传递,并有外层View的onT方法进行处理,以此类推。
- 如果事件在向内层传递过程中由于人为干预,事件处理函数返回true,则事件会提前消费掉,内层View将不会收到该事件。
- View控件的事件触发顺序是先执行onTouch方法,在最后才执行onClick方法。如果onTounch返回true。则事件终止传递,最后也不会调用onClick方法;如果onTouch返回false,则事件继续传递。
1.5 ViewGroup的事件传递机制
ViewGroup拥有dispatchTouchEvent、onInterceptTouchEvent和onTouchEvent三个方法。
事件传递流程图如下:
从上面流程图得出结论:
- 触摸事件的传递顺序是由Activity到ViewGroup,再由ViewGroup递归传递给其子View;
- ViewGroup通过onInterceptTouchEvent方法对事件进行拦截,该方法若返回true,则事件不会继续传递给子View,若返回false或者super.onInterceptTouchEvent,则事件会继续传递给子View。
- 在子View中对事件进行消费后,ViewGroup将接受不到任何事件。