**
view的事件分发:
** 事件分发需要View的三个重要方法来共同完成: public boolean dispatchTouchEvent(MotionEvent event) 事件分发,如果一个MotionEvent传递给了View,那么dispatchTouchEvent方法一定会被调用返回true表示事件被消费,本次的事件终止。 返回值:false表示View以及子View均没有消费事件,将调用父View的onTouchEvent方法; public boolean onInterceptTouchEvent(MotionEvent ev) 事件拦截,当一个ViewGroup在接到MotionEvent事件序列时候,首先会调用此方法判断是否需要拦截。特别注意,这是ViewGroup特有的方法,View并没有拦截方法 返回值:是否拦截事件传递,返回true表示拦截了事件,那么事件将不再向下分发而是调用View本身的onTouchEvent方法。返回false表示不做拦截,事件将向下分发到子View的dispatchTouchEvent方法。 public boolean onTouchEvent(MotionEvent ev) 真正对MotionEvent进行处理或者说消费的方法。 返回值:返回true表示事件被消费,本次的事件终止。返回false表示事件没有被消费,将调用父View的onTouchEvent方法
*MotionEvent:*我们对屏幕的点击,滑动,抬起等一系的动作都是由一个一个MotionEvent对象组成的。根据不同动作,主要有以下三种事件类型:
1.ACTION_DOWN:手指刚接触屏幕,按下去的那一瞬间产生该事件 2.ACTION_MOVE:手指在屏幕上移动时候产生该事件 3.ACTION_UP:手指从屏幕上松开的瞬间产生该事件
从ACTION_DOWN开始到ACTION_UP结束我们称为一个事件序列正常情况下,无论你手指在屏幕上有多么骚的操作,最终呈现在MotionEvent上来讲无外乎下面两种。 1.点击后抬起,也就是单击操作:ACTION_DOWN -> ACTION_UP 2.点击后再滑动一段距离,再抬起:ACTION_DOWN -> ACTION_MOVE -> … -> ACTION_MOVE -> ACTION_UP 上面三个主要的事件分发方法如果从伪代码的角度来看,关系应该是如下的:
public boolean dispatchTouchEvent(MotionEvent ev) {
boolean consume = false;
if (onInterceptTouchEvent(ev)){
consume = onTouchEvent(ev);
}else{
consume = child.dispatchTouchEvent(ev);
}
return consume;
}
一些重要的结论:
1.事件传递优先级:onTouchListener.onTouch > onTouchEvent > onClickListener.onClick。 2.正常情况下,一个时间序列只能被一个View拦截且消耗。因为一旦一个元素拦截了此事件,那么同一个事件序列内的所有事件都会直接交给它处理(即不会再调用这个View的拦截方法去询问它是否要拦截了,而是把剩余的ACTION_MOVE、ACTION_DOWN等事件直接交给它来处理)。特例:通过将重写View的onTouchEvent返回false可强行将事件转交给其他View处理。 3.如果View不消耗除ACTION_DOWN以外的其他事件,那么这个点击事件会消失,此时父元素的onTouchEvent并不会被调用,并且当前View可以持续收到后续的事件,最终这些消失的点击事件会传递给Activity处理。 4.ViewGroup默认不拦截任何事件(返回false)。 5.View的onTouchEvent默认都会消耗事件(返回true),除非它是不可点击的(clickable和longClickable同时为false)。View的longClickable属性默认都为false,clickable属性要分情况,比如Button的clickable属性默认为true,而TextView的clickable默认为false。 6.View的enable属性不影响onTouchEvent的默认返回值。 7.通过requestDisallowInterceptTouchEvent方法可以在子元素中干预父元素的事件分发过程,但是ACTION_DOWN事件除外,因为down事件会调用resetTouchState,清空所有的flag **
handler消息机制:
消息机制主要包含:MessageQueue,Handler和Looper这三大部分,以及Message,下面我们一一介绍: Message:需要传递的消息,可以传递数据; MessageQueue:消息队列,但是它的内部实现并不是用的队列,实际上是通过一个单链表的数据结构来维护消息列表,因为单链表在插入和删除上比较有优势。主要功能向消息池投递消息(MessageQueue.enqueueMessage)和取走消息池的消息(MessageQueue.next); Handler:消息辅助类,主要功能向消息池发送各种消息事件(Handler.sendMessage)和处理相应消息事件(Handler.handleMessage); Looper:不断循环执行(Looper.loop),从MessageQueue中读取消息,按分发机制将消息分发给目标处理者。
|