浅谈Android 事件分发机制(一)
2019-01-13 22:50
726 查看
Android事件分发机制是Android开发者必须了解的知识,这方面的内容很多,自己纯看文章总觉得比较抽象,自己写了个demo,理一下事件分发的流程,加深印象。
view结构
PhoneWindow 的指示通过 DecorView 传递给下面的 View,下面 View 的信息也通过 DecorView 回传给 PhoneWindow。这里我们主要聊聊ViewGroup与view的事件分发
事件分发
dispatchTouchEvent一般改写不多,主要关注另外两个。
事件拦截
onInterceptTouchEvent,true,拦截,交给自己的onTouchEvent处理,不传给下级;false,不拦截,传给下级。
事件消费
onTouchEvent,true,自己搞定消费,不用上传;false,上传。
事件模拟
如图布局,最外层的父布局ViewGroupA,中间层的ViewGroupB,最里层的ViewC
<?xml version="1.0" encoding="utf-8"?> <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" xmlns:app="http://schemas.android.com/apk/res-auto"> <com.qhyccd.event.ViewGroupA app:layout_constraintTop_toTopOf="parent" android:layout_marginTop="100dp" android:layout_width="300dp" android:layout_height="300dp" android:background="@color/colorRed"> <com.qhyccd.event.ViewGroupB android:layout_width="200dp" android:layout_height="200dp" android:background="@color/colorYellow"> <com.qhyccd.event.ViewC android:layout_width="100dp" android:layout_height="100dp" android:background="@color/colorBlue" /> </com.qhyccd.event.ViewGroupB> </com.qhyccd.event.ViewGroupA> </FrameLayout>
首先模拟下以上场景,A、B、C三个角色,A>B>C
ViewGroupA
public class ViewGroupA extends LinearLayout { public ViewGroupA(Context context) { super(context); } public ViewGroupA(Context context, @Nullable AttributeSet attrs) { super(context, attrs); } public ViewGroupA(Context context, @Nullable AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); } @Override public boolean dispatchTouchEvent(MotionEvent ev) { Log.i("》》》", " ViewGroupA dispatchTouchEvent "); return super.dispatchTouchEvent(ev); } @Override public boolean onInterceptTouchEvent(MotionEvent ev) { Log.i("》》》", " ViewGroupA onInterceptTouchEvent "); return super.onInterceptTouchEvent(ev); } @Override public boolean onTouchEvent(MotionEvent event) { Log.i("》》》", " ViewGroupA onTouchEvent "); return super.onTouchEvent(event); } }
ViewGroupB
public class ViewGroupB extends LinearLayout { public ViewGroupB(Context context) { super(context); } public ViewGroupB(Context context, @Nullable AttributeSet attrs) { super(context, attrs); } public ViewGroupB(Context context, @Nullable AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); } @Override public boolean dispatchTouchEvent(MotionEvent ev) { Log.i("》》》", " ViewGroupB dispatchTouchEvent "); return super.dispatchTouchEvent(ev);; } @Override public boolean onInterceptTouchEvent(MotionEvent ev) { Log.i("》》》", " ViewGroupB onInterceptTouchEvent "); return super.onInterceptTouchEvent(ev); } @Override public boolean onTouchEvent(MotionEvent event) { Log.i("》》》", " ViewGroupB onTouchEvent "); return super.onTouchEvent(event); } }
ViewC
public class ViewC extends View { public ViewC(Context context) { super(context); } public ViewC(Context context, @Nullable AttributeSet attrs) { super(context, attrs); } public ViewC(Context context, @Nullable AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); } @Override public boolean dispatchTouchEvent(MotionEvent event) { Log.i("》》》", " ViewC dispatchTouchEvent "); return super.dispatchTouchEvent(event); } @Override public boolean onTouchEvent(MotionEvent event) { Log.i("》》》", " ViewC onTouchEvent "); return super.onTouchEvent(event); } }
情景一
默认情况下,点击C区域
ViewGroupA dispatchTouchEvent ViewGroupA onInterceptTouchEvent ViewGroupB dispatchTouchEvent ViewGroupB onInterceptTouchEvent ViewC dispatchTouchEvent ViewC onTouchEvent ViewGroupB onTouchEvent ViewGroupA onTouchEvent
可见,事件是从A->B->C,再从C->B->A回传
情景二
A想自己把事件拦截,不给下级处理,A里面
onInterceptTouchEvent返回ture拦截事件
ViewGroupA dispatchTouchEvent ViewGroupA onInterceptTouchEvent ViewGroupA onTouchEvent
情景三
B想自己把事件拦截,不给下级处理,B里面
onInterceptTouchEvent返回ture拦截事件。
ViewGroupA dispatchTouchEvent ViewGroupA onInterceptTouchEvent ViewGroupB dispatchTouchEvent ViewGroupB onInterceptTouchEvent ViewGroupB onTouchEvent ViewGroupA onTouchEvent
B这里只是对事件拦截不往下传递,还是会往上回传的。
如果想让B自己把事件消费,不往上级传递,B的
onTouchEvent返回true
ViewGroupA dispatchTouchEvent ViewGroupA onInterceptTouchEvent ViewGroupB dispatchTouchEvent ViewGroupB onInterceptTouchEvent ViewGroupB onTouchEvent
情景四
C属于最底层view,对事件没有拦截权限,C自己想把事件消费了,C的
onTouchEvent返回
true,不再往上级回传
ViewGroupA dispatchTouchEvent ViewGroupA onInterceptTouchEvent ViewGroupB dispatchTouchEvent ViewGroupB onInterceptTouchEvent ViewC dispatchTouchEvent ViewC onTouchEvent
以上是静态点击事件处理流程,模拟的事件分发机制,通过log打印可以看到事件的传递流程,这篇文章属于基础篇章,后续我们给view添加滑动,通过处理滑动冲突进一步理解事件的分发机制,敬请期待下一篇。
相关文章推荐
- 浅谈Android 的事件分发机制
- Android面试补习(六)浅谈Android事件分发机制(对CSDN移动端的填坑意见反馈)
- 浅谈android事件分发机制
- Android——浅谈事件分发机制
- 浅谈Android事件分发机制(一)点击事件的传递规则
- 浅谈android的事件分发机制
- 浅谈Android 触摸事件分发机制
- 浅谈android view事件分发机制
- 浅谈Android事件分发机制
- Android 事件分发机制具体解释
- Android事件分发机制完全解析,带你从源码的角度彻底理解(上) .
- Android事件分发机制完全解析,带你从源码的角度彻底理解(上)
- Android事件分发机制解析
- android事件分发机制之View篇
- Android的事件分发机制
- Android事件分发机制完全解析,带你从源码的角度彻底理解(上)
- Android ----------- 事件分发 机制 研究
- 【漫画技术】揭秘Android事件分发机制
- Android触摸事件分发机制之requestDisallowInterceptTouchEvent
- android touch事件的分发和消费机制