Android自定义View移动开发首页投稿(暂停使用,暂停投稿)

Android开发艺术探索笔记——View(二)

2016-08-04  本文已影响102人  soberbad

Android开发艺术探索笔记——View(二)

View的事件分发机制

学习资料:
1.Understanding Android Input Touch Events System Framework
2.Managing Touch Events in a ViewGroup
3.Android事件传递机制
4.Input Events
5.Mastering the Android Touch System
6.MotionEvent

MotionEvent(运动事件)的传递规则

用户每次触摸屏幕都被包装成了MotionEvent(运动事件)对象

属性有:

View的事件分发,就是对MotionEvent事件的分发过程。

事件分发的三个重要方法:

//用于分发事件(dispatch touch event),要么将事件向下传递到目标View,要么交由自己处理。
//返回true表示自己处理
public boolean dispatchTouchEvent (MotionEvent event)


//用于拦截事件(intercept touch event),ViewGroup中有,View中没有这个方法。
public boolean onInterceptTouchEvent (MotionEvent event)


//用于处理事件
public boolean onTouchEvent (MotionEvent event)

三个方法的关系可用如下伪代码描述:

public boolean dispatchTouchEvent(MotionEvent ev){
   boolean consume = false;
   if(onInterceptTouchEvent(ev)){
     consume = true;
   }else{
     consume = child.dispatchTouchEvent(ev);
   }
   return consume;
}
viewTouchEvent

View的onTouchListener的优先级比onTouchEvent方法的高。

运动事件的传递顺序:

Activity-->Window-->View

下面是将ViewdispatchTouchEvent()方法设置断点后,点击ImageView的调试过程:

viewTouchEvent

能清楚地看到事件的传递过程和顺序。

若View的onTouchEvent()方法返回false,则会调用它的父View的onTouchEvent()方法,依此类推,若调用顺序上的所有View都不处理这个事件,则这个事件会最终传递给Activity的onTouchEvent()方法。

View的事件分发机制类似于互联网公司的工作流程:

 新任务:
 CEO-->产品经理-->CTO-->开发小组组长-->程序员
 
 由上至下一级一级分发任务(dispatchTouchEvent),如果是自己的任务(onInterceptTouchEvent)
 ,则拦截自己处理(onTouchEvent),反之,则交由下级分发(child.dispatchTouchEvent)。
 
 如果事情搞不定,就一级一级向上抛(parent.onTouchEvent):
 程序员-->开发组长-->CTO-->产品经理-->CEO
 

事件传递机制的一些结论:

事件分发源码解析

Activity对事件的分发过程

//Activity源码
 ...
 /*
  * Activity的dispatchTouchEvent方法
  */
 public boolean dispatchTouchEvent(MotionEvent ev) {
        if (ev.getAction() == MotionEvent.ACTION_DOWN) {
            onUserInteraction();
        }
        //Activity交由window进行事件分发
        if (getWindow().superDispatchTouchEvent(ev)) {
            return true;
        }
        return onTouchEvent(ev);
    }
//Window类是抽象类
public abstract class Window {
...
//window的superDispatchTouchEvent方法是抽象方法
public abstract boolean superDispatchTouchEvent(MotionEvent event);
...
}

而PhoneWindow类是Window类的唯一实现类。


public class PhoneWindow extends Window implements MenuBuilder.Callback {
...
  @Override
    public boolean superDispatchTouchEvent(MotionEvent event)       { 
    //PhoneWindow直接将事件交友DecorView处理
    return mDecor.superDispatchTouchEvent(event);
    }
 ...
 }

可以看到PhoneWindow类在实现抽象方法superDispatchTouchEvent时,直接将事件交由DecorView处理。

上一篇下一篇

猜你喜欢

热点阅读