View树的根View永远是DecorView,它继承自FrameLyout。其内部会有一个LinearLayout,依据Window Feather的的不同,LinearLayout内部的布局也不同,当中每种不同布局的xml(系统资源内部的xml布局)内都有一个id为content的FrameLayout。这就是我们在自己的布局所attach的父容器。
Touch事件的传递自然是先从ViewRootImpl传递到DecorView中。这个前面的第三点也说到了,因此我们这里就从DecorView入手,开始分析Touch事件的分发。
在开始分析之前,先大致梳理下Touch事件传递可能涉及到的一些基础:
1、普通情况下。每个Touch事件,总是以ACTION_DOWN事件开始。中间穿插着一些ACTION_MOVE事件(取决于是否有手势的移动),然后以ACTION_UP事件结束。中间还会会有onTouch、Click、LongClick等事件。
2、事件分发过程中,包含对MotionEvent事件的三种处理操作:
分发操作:dispatchTouchEvent方法,后面两个方法都是在该方法中被调用的。
拦截操作:onInterceptTouchEvent方法(ViewGroup)
消费操作:onTouchEvent方法和OnTouchListener的onTouch方法,当中onTouch的优先级高于onTouchEvent,若onTouch返回true。那么就不会调用onTouchEvent方法。
3、dispatchTouchEvent分发Touch事件是自顶向下,而onTouchEvent消费事件时自底向上。onTouchEvent和onIntercepteTouchEvent都是在dispatchTouchEvent
中被调用的。
以下,正式进入对Touch事件在View树中分发的分析:
首先来看DecorView(PhoneWindow的内部类)中dispatchTouchEvent方法:
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
final Callback cb = getCallback();
return cb != null && !isDestroyed() && mFeatureId < 0 ? cb.dispatchTouchEvent(ev)
: super.dispatchTouchEvent(ev);
}
这里的cb就是当前的Activity,Activity实现了Window.Callback接口,同一时候在Activity的attach方法中。创建PhoneWindow后。调用了
mWindow.setCallback(this)将PhoneWindow中的callback设置为当前的的Activity,因此这里cb.dispatchTouchEvent就是Activity的
dispatchTouchEvent方法,假设前面三个条件同一时候成立(通常是都成立的),则调用Activity的dispatchTouchEvent方法进行事件的分发。
否则。直接调用super.dispatchTouchEvent方法,也即是FrameLayout的dispatchTouchEvent方法,事实上即使调用了Activity的
本文来自电脑杂谈,转载请注明本文网址:
http://www.pc-fly.com/a/shouji/article-84984-4.html
雷不死给了多少钱