最近做的一个东西涉及到各种手势的操作,简单整理了下思路,对其中涉及到的MotionEvent,onTouch等等有了些简单的认识,现在简单整理下希望能帮助自己记忆,也希望能帮助到有需要的兄弟们。
首先从java或者Android的事件机制说起,完全是自己的理解,有什么不对的地方,还希望大家拍砖。说起事件一般不外乎需要三个东西:事件,事件监听器,事件源。
事件:一般封装了事件实体和相关信息。
事件监听器:事件监听,注册在事件源上,当事件源的属性或状态改变时,取得相应的监听器调用其内部的回调方法。
事件源:触发事件的地方,由于事件源的某项属性或状态发生了改变
写个简单实例:
1:事件
class Event{
public String msg;
public Event(){
}
}
2:监听(一般会是实现接口)
class EventListener implements lister{
public EventListener()
{
}
hanlerEvent(Event eve){
}
}
3:事件源
class EventSource{
EventListener eventListener;
setListener(EventListener eventListener){
this.eventListener=eventListener;
}
method(){
if(eventListener!=null)
{
Event eve=new Event();
eve.msg="Test";
eventListener.hanlerEvent(eve);
}}
}
4:测试代码
EventSource eventSource=new EventSource ();
events.setListener(new EventListener(){
hanlerEvent(Event eve){
System.out.println(eve.msg);
}
});
代码随手写的,仅供理解用。
拿着这个思路来看MotionEvent,也就是事件,里边封装着发生的事件,触控位置等逻辑,对于其中的实现可产看源代码:
源代码:http://www.oschina.net/code/explore/android-4.0.1/core/java/android/view/MotionEvent.java
以及介绍的一篇博文:
博文:http://my.oschina.net/banxi/blog/56421
有了事件,那就看一下事件监听,上源代码,那肯定OntouchEventListener
public interface OnTouchListener {
/***
* Called when a touch event is dispatched to a view. This allows listeners to
* get a chance to respond before the target view.
*
* @param v The view the touch event has been dispatched to.
* @param event The MotionEvent object containing full information about
* the event.
* @return True if the listener has consumed the event, false otherwise.
*/
boolean onTouch(View v, MotionEvent event);
}
然后就看事件源,这里以View为例,View源码:http://www.oschina.net/code/explore/android-4.0.1/core/java/android/view/View.java
事件流在Android里比较复杂,这里以View中处理开始说:
首先是dispatchPointerEvent方法,这个方法不用多说:
public final boolean dispatchPointerEvent(MotionEvent event) {
if (event.isTouchEvent()) {
return dispatchTouchEvent(event);
} else {
return dispatchGenericMotionEvent(event);
}
}
再就是dispatchTouchEvent,这里需要注意的是,在View和ViewGroup里处理不用,不注意可能会引发手势不响应的情况,下边提供的博文地址里会有说。
public boolean dispatchTouchEvent(MotionEvent event) {
if (mInputEventConsistencyVerifier != null) {
mInputEventConsistencyVerifier.onTouchEvent(event, 0);
}
if (onFilterTouchEventForSecurity(event)) {
//noinspection SimplifiableIfStatement
if (mOnTouchListener != null && (mViewFlags & ENABLED_MASK) == ENABLED &&
mOnTouchListener.onTouch(this, event)) {
return true;
}
if (onTouchEvent(event)) {
return true;
}
}
if (mInputEventConsistencyVerifier != null) {
mInputEventConsistencyVerifier.onUnhandledEvent(event, 0);
}
return false;
}
上边的代码可以看到如果没有监听,就会进入View的onTouch事件
如果有监听会进入监听的毁掉函数。
对于详细的事件流可以参考博文,里边说的很详细,这里就不赘述了,博文地址:http://www.eyeandroid.com/thread-17129-1-1.html
简单总结下事件传递分发机制:
事件触发后主要看三个函数:dispatchTouchEvent
,onTouchEvent
,onInterceptTouchEvent
三个的作用如下:
dispatchTouchEvent
方法用于事件的分发,Android中所有的事件都必须经过这个方法的分发,然后决定是自身消费当前事件还是继续往下分发给子控件处理。返回true表示不继续分发,事件没有被消费。返回false则继续往下分发,如果是ViewGroup则分发给onInterceptTouchEvent进行判断是否拦截该事件。onTouchEvent
方法用于事件的处理,返回true表示消费处理当前事件,返回false则不处理,交给子控件进行继续分发。onInterceptTouchEvent
是ViewGroup中才有的方法,View中没有,它的作用是负责事件的拦截,返回true的时候表示拦截当前事件,不继续往下分发,交给自身的onTouchEvent进行处理。返回false则不拦截,继续往下传。这是ViewGroup特有的方法,因为ViewGroup中可能还有子View,而在Android中View中是不能再包含子View的