您的位置:首页 > 移动开发 > Android开发

android touch事件 续(一)

2015-12-13 16:18 501 查看
如果不了解事件分发原理的,就不要读这博客了,本博客只是对理解事件分发的补充

很久之前读了别人的touch事件分发,发现自己理解了,然后从源码理解了一遍,大致有了了解。但是现在一用,又发现新的问题了

当时了解的是父子view之间的点击事件分发,但是,如果是平级呢?

问题一:如果两个view是平级,而不是父子关系,那么事件会怎么分发?

带着这个疑问,我写了个代码实验,一个viewPage(有滑动),一个Button(有点击)或者textView(无点击),button在viewpage上面(即button覆盖了viewpage的一部分)

1. 两次运行后,发现,如果是button + viewpage,那么,当down事件从button外面(即viewPager)触发时候,这一套事件都是属于viewPager的,如果是从button里面触发,那么这一套事件都是属于button的,这个相信大家都理解(决定事件归属权就是这样决定的

2. 如果是textView + viewPager,那么,无论down事件是在textView的外面,还是里面,触发的都是viewPager的处理,也就是说,这一套事件的归属权都是属于viewPager的,为什么会这样?

首先,事件确实经过了textView的onTouchEvent方法,即,确实分给了textView,但是textView是不可点击的,所以返回了false。

大致流程是,父viewGroup分发给textView,textView dispathTouchEvent 直接返回onTouchEvent,onTouchEvent直接返回false,就是说,接下来会进入下一次循环,给其他子view尝试判断分发。

这里copy了别人源码分析中的viewGroup的ontouchEvent方法中的相关代码片段(不建议看高版本的源码,因为高版本代码加了许多处理,看起来没有那么直观)

if (disallowIntercept || !onInterceptTouchEvent(ev)) {
ev.setAction(MotionEvent.ACTION_DOWN);
final int scrolledXInt = (int) scrolledXFloat;
final int scrolledYInt = (int) scrolledYFloat;
final View[] children = mChildren;
final int count = mChildrenCount;
for (int i = count - 1; i >= 0; i--) {
final View child = children[i];
if ((child.mViewFlags & VISIBILITY_MASK) == VISIBLE
|| child.getAnimation() != null) {
child.getHitRect(frame);
if (frame.contains(scrolledXInt, scrolledYInt)) {
final float xc = scrolledXFloat - child.mLeft;
final float yc = scrolledYFloat - child.mTop;
ev.setLocation(xc, yc);
child.mPrivateFlags &= ~CANCEL_NEXT_UP_EVENT;
if (child.dispatchTouchEvent(ev))  {
mMotionTarget = child;
return true;
}
}
}
}
}


实际上,button(TextView) + viewPager都是放在一个viewGroup中的,所以,也需要用事件分发的远离来理解,之前虽然明白这一点,但是思考的时候没有联系起来,所以有点糊涂。

附上一张我认为的窗口结构

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: