当前位置: 首页 > news >正文

Activity事件分发机制

一、事件分发的基本概念

1、MotionEvent View触摸事件通过MotionEvent来表示,主要分为:

  • ACTION_DOWN:手指按下
  • ACTION_UP:手指抬起
  • ACTION_MOVE:手指移动
  • ACTION_CANCEL:非正常取消

2、当View的点击事件产生后,首先传递到Activity上,然后一层层传递到ViewGroup中,最终传递到View中。
3、事件分发主要的三个方法:

  • dispatchTouchEvent:事件分发的方法
  • onInterceptTouchEvent:事件拦截的方法。在Activity和View都没有这个方法,如果Activity拦截了那整个屏幕都无法响应事件,View作为事件最后的接收者,要么消耗,要么不处理,也不需要进行事件拦截。
  • onTouchEvent:事件处理的方法。返回值为true表示要消耗当前事件。

二、dispatchTouchEvent

   public boolean dispatchTouchEvent(MotionEvent ev) {
        if (ev.getAction() == MotionEvent.ACTION_DOWN) {
            onUserInteraction(); (1)
        }
        //window的dispatchTouchEvent方法返回为true时,该方法返回true,否者执行onTouchEvent方法
        if (getWindow().superDispatchTouchEvent(ev)) { (2)
            return true;
        }
        return onTouchEvent(ev);
    }
复制代码

(1)

public void onUserInteraction() {
}
复制代码

此方法为空方法。当此activity在栈顶时,触屏点击按home,back,menu键等都会触发此方法。下拉statubar、旋转屏幕、锁屏不会触发此方法。
(2) getWindow().superDispatchTouchEvent(ev): 调用了抽象类Window的superDispatchTouchEvent抽象方法。具体实现在哪? PhoneWindow是Window的唯一实现类。

**PhoneWindow**
Override
public boolean superDispatchTouchEvent(MotionEvent event) {
	return mDecor.superDispatchTouchEvent(event);
}
复制代码

内部调用了DecorView的superDispatchTouchEvent方法,

private final class DecorView extends FrameLayout implements RootViewSurfaceTaker {
    ......
}
复制代码
  • DecorView类是PhoneWindow类的一个内部类
  • DecorView继承自FrameLayout,是所有界面的父类
**DecorView**
public boolean superDispatchTouchEvent(MotionEvent event) {
        return super.dispatchTouchEvent(event);
}
复制代码

内部调用了ViewGroup的dispatchTouchEvent方法。

总结:getWindow().superDispatchTouchEvent(ev) 是调用了ViewGroup的dispatchTouchEvent方法。

三、onTouchEvent

public boolean onTouchEvent(MotionEvent event) {
        if (mWindow.shouldCloseOnTouch(this, event)) {
            finish();
            return true;
        }

        return false;
    }
复制代码

总结:

  • 事件传递路径 Activity -> PhoneWindow -> DecorView -> ViewGroup
  • Activity的dispatchTouchEvent方法调用了ViewGroup的dispatchTouchEvent方法,并且如果其返回值为false,才会调用Activity的onTouchEvent方法,此时dispatchTouchEvent返回值受onTouchEvent方法返回值的影响。 (问题:啥时候ViewGroup的dispatchTouchEvent方法返回false,也就是说啥时候onTouchEvent方法会执行)

相关文章:

  • ListT常用操作函数
  • Tomcat 的连接数与线程池
  • JVM内存模型
  • windows下安装redis以及redis扩展,设置redis为windows自启服务
  • HTML中动态生成内容的事件绑定问题
  • Scala学习之路 (五)Scala的关键字Lazy
  • ListView封装实现下拉刷新和上拉加载
  • 搜狗旅行翻译宝亮相香港环球资源电子展 AI翻译成全场最大亮点
  • 43.AzureVM复制到另一个Azure区域
  • 如何在虚拟机中访问真机的虚拟域名
  • java中的hashCode
  • Hive连接?
  • 20165334 《java程序设计》第8周学习总结
  • Redis4.0 单节点集群到三主三从节点集群实验
  • 基于面向对象编程的设计模式
  • [数据结构]链表的实现在PHP中
  • 【EOS】Cleos基础
  • 10个确保微服务与容器安全的最佳实践
  • CentOS7简单部署NFS
  • co模块的前端实现
  • css属性的继承、初识值、计算值、当前值、应用值
  • el-input获取焦点 input输入框为空时高亮 el-input值非法时
  • EventListener原理
  • Java 内存分配及垃圾回收机制初探
  • Java基本数据类型之Number
  • Laravel 实践之路: 数据库迁移与数据填充
  • PHP 使用 Swoole - TaskWorker 实现异步操作 Mysql
  • Python 基础起步 (十) 什么叫函数?
  • Spark VS Hadoop:两大大数据分析系统深度解读
  • 订阅Forge Viewer所有的事件
  • 关于springcloud Gateway中的限流
  • 前端存储 - localStorage
  • 如何抓住下一波零售风口?看RPA玩转零售自动化
  • 使用iElevator.js模拟segmentfault的文章标题导航
  • 使用前端开发工具包WijmoJS - 创建自定义DropDownTree控件(包含源代码)
  • 数据仓库的几种建模方法
  • 王永庆:技术创新改变教育未来
  • C# - 为值类型重定义相等性
  • ​linux启动进程的方式
  • #mysql 8.0 踩坑日记
  • #stm32整理(一)flash读写
  • #Z2294. 打印树的直径
  • ()、[]、{}、(())、[[]]命令替换
  • (10)STL算法之搜索(二) 二分查找
  • (PyTorch)TCN和RNN/LSTM/GRU结合实现时间序列预测
  • (六)c52学习之旅-独立按键
  • (转)iOS字体
  • ./和../以及/和~之间的区别
  • .NET 8 编写 LiteDB vs SQLite 数据库 CRUD 接口性能测试(准备篇)
  • .NET Core 和 .NET Framework 中的 MEF2
  • .netcore 如何获取系统中所有session_如何把百度推广中获取的线索(基木鱼,电话,百度商桥等)同步到企业微信或者企业CRM等企业营销系统中...
  • .NET项目中存在多个web.config文件时的加载顺序
  • .so文件(linux系统)
  • @Import注解详解
  • @Not - Empty-Null-Blank