Android事件分发机制是Android开发者必须了解的知识,这方面的内容很多,自己纯看文章总觉得比较抽象,自己写了个demo,理一下事件分发的流程,加深印象。

view结构

浅谈Android 事件分发机制(一)_第1张图片 image

PhoneWindow 的指示通过 DecorView 传递给下面的 View,下面 View 的信息也通过 DecorView 回传给 PhoneWindow。这里我们主要聊聊ViewGroup与view的事件分发

注‘Android技术交流群878873098,欢迎大家加入交流,畅谈!本群有免费学习资料视频且免费分享

浅谈Android 事件分发机制(一)_第2张图片 image

事件分发dispatchTouchEvent一般改写不多,主要关注另外两个。
事件拦截onInterceptTouchEvent,true,拦截,交给自己的onTouchEvent处理,不传给下级;false,不拦截,传给下级。
事件消费onTouchEvent,true,自己搞定消费,不用上传;false,上传。

事件模拟

浅谈Android 事件分发机制(一)_第3张图片 image

如图布局,最外层的父布局ViewGroupA,中间层的ViewGroupB,最里层的ViewC

<?xml version="1.0" encoding="utf-8"?>                                    

首先模拟下以上场景,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 dispatchTouchEventViewGroupA onInterceptTouchEventViewGroupB dispatchTouchEvent  ViewGroupB onInterceptTouchEvent  ViewC dispatchTouchEvent ViewC onTouchEvent  ViewGroupB onTouchEvent  ViewGroupA onTouchEvent

可见,事件是从A->B->C,再从C->B->A回传

情景二

A想自己把事件拦截,不给下级处理,A里面onInterceptTouchEvent返回ture拦截事件

ViewGroupA dispatchTouchEvent ViewGroupA onInterceptTouchEventViewGroupA onTouchEvent

情景三

B想自己把事件拦截,不给下级处理,B里面onInterceptTouchEvent返回ture拦截事件。

ViewGroupA dispatchTouchEventViewGroupA onInterceptTouchEventViewGroupB dispatchTouchEvent  ViewGroupB onInterceptTouchEvent  ViewGroupB onTouchEvent  ViewGroupA onTouchEvent

B这里只是对事件拦截不往下传递,还是会往上回传的。
如果想让B自己把事件消费,不往上级传递,B的onTouchEvent返回true

ViewGroupA dispatchTouchEventViewGroupA onInterceptTouchEventViewGroupB dispatchTouchEvent  ViewGroupB onInterceptTouchEvent  ViewGroupB onTouchEvent

情景四

C属于最底层view,对事件没有拦截权限,C自己想把事件消费了,C的onTouchEvent返回true,不再往上级回传

ViewGroupA dispatchTouchEventViewGroupA onInterceptTouchEventViewGroupB dispatchTouchEvent  ViewGroupB onInterceptTouchEvent  ViewC dispatchTouchEvent ViewC onTouchEvent

以上是静态点击事件处理流程,模拟的事件分发机制,通过log打印可以看到事件的传递流程,这篇文章属于基础篇章,后续我们给view添加滑动,通过处理滑动冲突进一步理解事件的分发机制,敬请期待下一篇。

注‘Android技术交流群878873098,欢迎大家加入交流,畅谈!本群有免费学习资料视频且免费分享

更多相关文章

  1. 对android里布局文件当中的TextView对象设置事件监听,但是不响应
  2. (4.1.21.4)Android Handler 异步消息处理机制的妙用 创建强大的图
  3. [转]Android 应用初始化及窗体事件(按键)的分发 [此博文包含图片]
  4. android的消息处理机制(图+源码分析)——Looper,Handler,Message (
  5. android处理键盘事件之物理按键 (一)
  6. Android触摸事件的分发处理
  7. Android——消息机制中的Message Pool是个什么鬼,Message Pool会

随机推荐

  1. android 通过资源文件名称获取资源文件id
  2. Android ——Window类
  3. 【Android】_SmsReceicer_短信监听
  4. Android Gradle 基础认识
  5. 指定浏览器访问指定页面(支持UC、Opera、
  6. Android入门之SeekBar
  7. @android:style/Theme.Dialog 和 @style/
  8. 三、mono for android 学习:参考书籍
  9. LocationManager Android自动定位使用以
  10. Hardware Acceleration | Android Develo