今天做了一些关于Android Touch时间的传递机制的研究,研究的结果是:
1. 点击事件是可以穿透View的;如果置于表层的View没有处理该事件,则被覆盖的View是可以接收到这个事件的。因为,屏幕上我们所创建的View,都是屏幕的根容器的Child。而ViewGroup在dispatchTouchEvent时,会将事件依次传递给各个Child。
2. 可以发现,dispatchTouchEvent这个函数是一个类似于递归调用的函数。其流程是:
如果
1. View不为ViewGroup
2. View为ViewGroup,但是没有Child
2. View截获了这个事件,即在onInterceptTouchEvent中返回了True
则:将TouchEvent传递给onTouchEvent进行处理,然后dispatchTouchEvent结束。
否则:View遍历并调用所有的Child的dispatchTouchEvent
3. 如果某个子View在Down时返回了True,则代表:我关心这个Touch系列时间;因此,如果上层没有intercept事件,以后的Move、Up等时间,都会传递给该View;就算该View在其他的Move事件中返回了false,接下来的事件依旧会传递到这个View中。
4. 如果子View在onTouchEvent中返回了True,则父类的onTouchEvent是接收不到TouchEvent的,除非调用onInterceptTouchEvent。
5. 如果整个链条中都没有人在onTouchEvent中返回True,则之后的一系列事件,不会再传递给这个ViewGroup了。
下面是我的测试代码和测试输出,有兴趣可以看一下。
以下是View的层次结构:
MyLinearLayout派生自Linearlayout,只是在三个关于TouchEvent传递的函数dispatchTouchEvent, onInterceptTouchEvent, onTouchEvent中输出了当前的状态。
public View getMyView()
{
MyLinearLayout root = new MyLinearLayout(this);
MyLinearLayout layout = root;
for (int i=0; i<5; i++)
{
MyLinearLayout view = new MyLinearLayout(this);
layout.addView(view, new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
layout = view;
}
return root;
}
1. 所有的onInterceptTouchEvent和onTouchEvent都没有做任何处理;即都返回false
E/Touch Test(18929): Level 0: dispatchTouchEvent begin::Down
E/Touch Test(18929): Level 0: onInterceptTouchEvent:Down: return false
E/Touch Test(18929): —— Level 1: dispatchTouchEvent begin::Down
E/Touch Test(18929): —— Level 1: onInterceptTouchEvent:Down: return false
E/Touch Test(18929): —— —— Level 2: dispatchTouchEvent begin::Down
E/Touch Test(18929): —— —— Level 2: onInterceptTouchEvent:Down: return false
E/Touch Test(18929): —— —— —— Level 3: dispatchTouchEvent begin::Down
E/Touch Test(18929): —— —— —— Level 3: onInterceptTouchEvent:Down: return false
E/Touch Test(18929): —— —— —— —— Level 4: dispatchTouchEvent begin::Down
E/Touch Test(18929): —— —— —— —— Level 4: onInterceptTouchEvent:Down: return false
E/Touch Test(18929): —— —— —— —— Level 4: onTouchEvent:Down: return false
E/Touch Test(18929): —— —— —— —— Level 4: dispatchTouchEvent end::Down: return false
E/Touch Test(18929): —— —— —— Level 3: onTouchEvent:Down: return false
E/Touch Test(18929): —— —— —— Level 3: dispatchTouchEvent end::Down: return false
E/Touch Test(18929): —— —— Level 2: onTouchEvent:Down: return false
E/Touch Test(18929): —— —— Level 2: dispatchTouchEvent end::Down: return false
E/Touch Test(18929): —— Level 1: onTouchEvent:Down: return false
E/Touch Test(18929): —— Level 1: dispatchTouchEvent end::Down: return false
E/Touch Test(18929): Level 0: onTouchEvent:Down: return false
E/Touch Test(18929): Level 0: dispatchTouchEvent end::Down: return false
2. Level 3,onInterceptTouchEvent返true,其他的onInterceptTouchEvent返回false;
所有的onTouchEvent返回false
E/Touch Test(27070): Level 0: dispatchTouchEvent begin::Down
E/Touch Test(27070): Level 0: onInterceptTouchEvent:Down: return false
E/Touch Test(27070): —— Level 1: dispatchTouchEvent begin::Down
E/Touch Test(27070): —— Level 1: onInterceptTouchEvent:Down: return false
E/Touch Test(27070): —— —— Level 2: dispatchTouchEvent begin::Down
E/Touch Test(27070): —— —— Level 2: onInterceptTouchEvent:Down: return false
E/Touch Test(27070): —— —— —— Level 3: dispatchTouchEvent begin::Down
E/Touch Test(27070): —— —— —— Level 3: onInterceptTouchEvent:Down: return true
E/Touch Test(27070): —— —— —— Level 3: onTouchEvent:Down: return false
E/Touch Test(27070): —— —— —— Level 3: dispatchTouchEvent end::Down: return false
E/Touch Test(27070): —— —— Level 2: onTouchEvent:Down: return false
E/Touch Test(27070): —— —— Level 2: dispatchTouchEvent end::Down: return false
E/Touch Test(27070): —— Level 1: onTouchEvent:Down: return false
E/Touch Test(27070): —— Level 1: dispatchTouchEvent end::Down: return false
E/Touch Test(27070): Level 0: onTouchEvent:Down: return false
E/Touch Test(27070): Level 0: dispatchTouchEvent end::Down: return false
3. onInterceptTouchEvent都返回false;
在Level 3中onTouchEvent返回true;其他的onTouchEvent都返回false。
E/Touch Test(21314): Level 0: dispatchTouchEvent begin::Down
E/Touch Test(21314): Level 0: onInterceptTouchEvent:Down: return false
E/Touch Test(21314): —— Level 1: dispatchTouchEvent begin::Down
E/Touch Test(21314): —— Level 1: onInterceptTouchEvent:Down: return false
E/Touch Test(21314): —— —— Level 2: dispatchTouchEvent begin::Down
E/Touch Test(21314): —— —— Level 2: onInterceptTouchEvent:Down: return false
E/Touch Test(21314): —— —— —— Level 3: dispatchTouchEvent begin::Down
E/Touch Test(21314): —— —— —— Level 3: onInterceptTouchEvent:Down: return false
E/Touch Test(21314): —— —— —— —— Level 4: dispatchTouchEvent begin::Down
E/Touch Test(21314): —— —— —— —— Level 4: onInterceptTouchEvent:Down: return false
E/Touch Test(21314): —— —— —— —— Level 4: onTouchEvent:Down: return false
E/Touch Test(21314): —— —— —— —— Level 4: dispatchTouchEvent end::Down: return false
E/Touch Test(21314): —— —— —— Level 3: onTouchEvent:Down: return true
E/Touch Test(21314): —— —— —— Level 3: dispatchTouchEvent end::Down: return true
E/Touch Test(21314): —— —— Level 2: dispatchTouchEvent end::Down: return true
E/Touch Test(21314): —— Level 1: dispatchTouchEvent end::Down: return true
E/Touch Test(21314): Level 0: dispatchTouchEvent end::Down: return true
E/Touch Test(21314): Level 0: dispatchTouchEvent begin::Move
E/Touch Test(21314): Level 0: onInterceptTouchEvent:Move: return false
E/Touch Test(21314): —— Level 1: dispatchTouchEvent begin::Move
E/Touch Test(21314): —— Level 1: onInterceptTouchEvent:Move: return false
E/Touch Test(21314): —— —— Level 2: dispatchTouchEvent begin::Move
E/Touch Test(21314): —— —— Level 2: onInterceptTouchEvent:Move: return false
E/Touch Test(21314): —— —— —— Level 3: dispatchTouchEvent begin::Move
E/Touch Test(21314): —— —— —— Level 3: onTouchEvent:Move: return true
E/Touch Test(21314): —— —— —— Level 3: dispatchTouchEvent end::Move: return true
E/Touch Test(21314): —— —— Level 2: dispatchTouchEvent end::Move: return true
E/Touch Test(21314): —— Level 1: dispatchTouchEvent end::Move: return true
E/Touch Test(21314): Level 0: dispatchTouchEvent end::Move: return true
E/Touch Test(21314): Level 0: dispatchTouchEvent begin::Up
E/Touch Test(21314): Level 0: onInterceptTouchEvent:Up: return false
E/Touch Test(21314): —— Level 1: dispatchTouchEvent begin::Up
E/Touch Test(21314): —— Level 1: onInterceptTouchEvent:Up: return false
E/Touch Test(21314): —— —— Level 2: dispatchTouchEvent begin::Up
E/Touch Test(21314): —— —— Level 2: onInterceptTouchEvent:Up: return false
E/Touch Test(21314): —— —— —— Level 3: dispatchTouchEvent begin::Up
E/Touch Test(21314): —— —— —— Level 3: onTouchEvent:Up: return true
E/Touch Test(21314): —— —— —— Level 3: dispatchTouchEvent end::Up: return true
E/Touch Test(21314): —— —— Level 2: dispatchTouchEvent end::Up: return true
E/Touch Test(21314): —— Level 1: dispatchTouchEvent end::Up: return true
E/Touch Test(21314): Level 0: dispatchTouchEvent end::Up: return true
4. onInterceptTouchEvent都返回false;
在Level 3中onTouchEvent中,如果event为Down,则true;否则返回false;
其他的onTouchEvent都返回false。
E/Touch Test(3245): Level 0: dispatchTouchEvent begin::Down
E/Touch Test(3245): Level 0: onInterceptTouchEvent:Down: return false
E/Touch Test(3245): —— Level 1: dispatchTouchEvent begin::Down
E/Touch Test(3245): —— Level 1: onInterceptTouchEvent:Down: return false
E/Touch Test(3245): —— —— Level 2: dispatchTouchEvent begin::Down
E/Touch Test(3245): —— —— Level 2: onInterceptTouchEvent:Down: return false
E/Touch Test(3245): —— —— —— Level 3: dispatchTouchEvent begin::Down
E/Touch Test(3245): —— —— —— Level 3: onInterceptTouchEvent:Down: return false
E/Touch Test(3245): —— —— —— —— Level 4: dispatchTouchEvent begin::Down
E/Touch Test(3245): —— —— —— —— Level 4: onInterceptTouchEvent:Down: return false
E/Touch Test(3245): —— —— —— —— Level 4: onTouchEvent:Down: return false
E/Touch Test(3245): —— —— —— —— Level 4: dispatchTouchEvent end::Down: return false
E/Touch Test(3245): —— —— —— Level 3: onTouchEvent:Down: return true
E/Touch Test(3245): —— —— —— Level 3: dispatchTouchEvent end::Down: return true
E/Touch Test(3245): —— —— Level 2: dispatchTouchEvent end::Down: return true
E/Touch Test(3245): —— Level 1: dispatchTouchEvent end::Down: return true
E/Touch Test(3245): Level 0: dispatchTouchEvent end::Down: return true
E/Touch Test(3245): Level 0: dispatchTouchEvent begin::Move
E/Touch Test(3245): Level 0: onInterceptTouchEvent:Move: return false
E/Touch Test(3245): —— Level 1: dispatchTouchEvent begin::Move
E/Touch Test(3245): —— Level 1: onInterceptTouchEvent:Move: return false
E/Touch Test(3245): —— —— Level 2: dispatchTouchEvent begin::Move
E/Touch Test(3245): —— —— Level 2: onInterceptTouchEvent:Move: return false
E/Touch Test(3245): —— —— —— Level 3: dispatchTouchEvent begin::Move
E/Touch Test(3245): —— —— —— Level 3: onTouchEvent:Move: return false
E/Touch Test(3245): —— —— —— Level 3: dispatchTouchEvent end::Move: return false
E/Touch Test(3245): —— —— Level 2: dispatchTouchEvent end::Move: return false
E/Touch Test(3245): —— Level 1: dispatchTouchEvent end::Move: return false
E/Touch Test(3245): Level 0: dispatchTouchEvent end::Move: return false
E/Touch Test(3245): Level 0: dispatchTouchEvent begin::Up
E/Touch Test(3245): Level 0: onInterceptTouchEvent:Up: return false
E/Touch Test(3245): —— Level 1: dispatchTouchEvent begin::Up
E/Touch Test(3245): —— Level 1: onInterceptTouchEvent:Up: return false
E/Touch Test(3245): —— —— Level 2: dispatchTouchEvent begin::Up
E/Touch Test(3245): —— —— Level 2: onInterceptTouchEvent:Up: return false
E/Touch Test(3245): —— —— —— Level 3: dispatchTouchEvent begin::Up
E/Touch Test(3245): —— —— —— Level 3: onTouchEvent:Up: return false
E/Touch Test(3245): —— —— —— Level 3: dispatchTouchEvent end::Up: return false
E/Touch Test(3245): —— —— Level 2: dispatchTouchEvent end::Up: return false
E/Touch Test(3245): —— Level 1: dispatchTouchEvent end::Up: return false
E/Touch Test(3245): Level 0: dispatchTouchEvent end::Up: return false