android 从源码分析ViewGroup事件分发
2014-11-16 20:05
537 查看
今天讲下ViewGroup的事件分发,上次讲了view的事件分发,其实view并没有事件分发,只是这么讲的,view事件分发只是讲了click和touch事件,而viewgroup就不同了,比如listview嵌套listview,viewpager嵌套viewpager,当滑动的时候就会出现是滑动父view的,从而子view的滑动事件就没有被执行,因此解决方案就要弄清楚viewgroup的事件分发
现在自定义一个LinearLayout,我们知道LinearLayout是继承于ViewGroup,
布局:
界面上还有2个Button,现在给2个Button注册click,layout注册touch事件,
现在点击Button1 Button2,以及空白区域:log信息如下:
我们发现当点击button的时候layout并没有被执行,只有点击空白区域才会执行,我们上次在研究view的事件分发就说过自定义的view上首先会执行dispatchTouchEvent(),ViewGroup比View多了一个方法就是onInterceptTouchEvent(),此方法表示拦截的意思,我们看下ViewGroup中的dispatchTouchEvent()方法源码:
待续
现在自定义一个LinearLayout,我们知道LinearLayout是继承于ViewGroup,
布局:
<com.example.viewpager.view.MyLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:id="@+id/layout" > <Button android:id="@+id/button1" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="button1" /> <Button android:id="@+id/button2" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="button2" /> </com.example.viewpager.view.MyLayout>
界面上还有2个Button,现在给2个Button注册click,layout注册touch事件,
现在点击Button1 Button2,以及空白区域:log信息如下:
我们发现当点击button的时候layout并没有被执行,只有点击空白区域才会执行,我们上次在研究view的事件分发就说过自定义的view上首先会执行dispatchTouchEvent(),ViewGroup比View多了一个方法就是onInterceptTouchEvent(),此方法表示拦截的意思,我们看下ViewGroup中的dispatchTouchEvent()方法源码:
public boolean dispatchTouchEvent(MotionEvent ev) { final int action = ev.getAction(); final float xf = ev.getX(); final float yf = ev.getY(); final float scrolledXFloat = xf + mScrollX; final float scrolledYFloat = yf + mScrollY; final Rect frame = mTempRect; boolean disallowIntercept = (mGroupFlags & FLAG_DISALLOW_INTERCEPT) != 0; if (action == MotionEvent.ACTION_DOWN) { if (mMotionTarget != null) { mMotionTarget = null; } 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; } } } } } } boolean isUpOrCancel = (action == MotionEvent.ACTION_UP) || (action == MotionEvent.ACTION_CANCEL); if (isUpOrCancel) { mGroupFlags &= ~FLAG_DISALLOW_INTERCEPT; } final View target = mMotionTarget; if (target == null) { ev.setLocation(xf, yf); if ((mPrivateFlags & CANCEL_NEXT_UP_EVENT) != 0) { ev.setAction(MotionEvent.ACTION_CANCEL); mPrivateFlags &= ~CANCEL_NEXT_UP_EVENT; } return super.dispatchTouchEvent(ev); } if (!disallowIntercept && onInterceptTouchEvent(ev)) { final float xc = scrolledXFloat - (float) target.mLeft; final float yc = scrolledYFloat - (float) target.mTop; mPrivateFlags &= ~CANCEL_NEXT_UP_EVENT; ev.setAction(MotionEvent.ACTION_CANCEL); ev.setLocation(xc, yc); if (!target.dispatchTouchEvent(ev)) { } mMotionTarget = null; return true; } if (isUpOrCancel) { mMotionTarget = null; } final float xc = scrolledXFloat - (float) target.mLeft; final float yc = scrolledYFloat - (float) target.mTop; ev.setLocation(xc, yc); if ((target.mPrivateFlags & CANCEL_NEXT_UP_EVENT) != 0) { ev.setAction(MotionEvent.ACTION_CANCEL); target.mPrivateFlags &= ~CANCEL_NEXT_UP_EVENT; mMotionTarget = null; } return target.dispatchTouchEvent(ev); }
待续
相关文章推荐
- Android中ViewGroup、View事件分发机制源码分析总结(雷惊风)
- Android View和ViewGroup事件分发机制源码分析
- Android应用开发原理之从ViewGroup源码分析ViewGroup的事件分发机制
- Android事件分发机制源码分析下----ViewGroup事件分发分析
- Android事件分发详解(三)——ViewGroup的dispatchTouchEvent()源码学习
- 从源码角度带你分析 Android View 事件分发 dispatchTouchEvent,onTouch,onTouchEvent,onClick逻辑顺序过程(一)
- Android触摸事件分发处理机制详解与源码分析一(View篇)
- Android事件分发详解(三)——ViewGroup的dispatchTouchEvent()源码学习
- Android View 事件分发机制 && Android ViewGroup 事件分发机制 源码解析 --总结
- Android事件分发详解(三)——ViewGroup的dispatchTouchEvent()源码学习
- Android事件分发详解(三)——ViewGroup的dispatchTouchEvent()源码学习
- Android中View和ViewGroup事件分发拦截机制完美分析
- Android触摸屏ViewGroup事件派发机制详解与源码分析
- Android事件分发之子View驳回ViewGroup拦截原理分析
- Android事件分发机制源码分析之View篇
- 源码解析---android中ViewGroup的事件分发机制
- Android 事件分发机制(最新源码6.0分析)--ViewGrop
- [置顶] 带你从源码角度分析ViewGroup中事件分发流程
- android源码分析之View的事件分发(上)
- Android开发-事件分发机制实验分析ViewGroup、View事件分发,结合职责链模式