onTouchEvent浅析

news2024/11/6 9:51:36

我们接着上次的自定义星星来作讲解
当 onTouchEvent 返回 super.onTouchEvent ( false ) 时

public boolean onTouchEvent(MotionEvent event) {
    switch (event.getAction()) {
        case MotionEvent.ACTION_DOWN:
            Log.d("ACTION_DOWN","ACTION_DOWN:"+event.getAction());
            break;
        case MotionEvent.ACTION_MOVE:
            Log.d("ACTION_MOVE","ACTION_MOVE:"+event.getAction());
            break;
        case MotionEvent.ACTION_UP:
            Log.d("ACTION_UP","ACTION_UP:"+event.getAction());
            break;
    }
    return super.onTouchEvent(event);
}

第一次会执行 DOWN 事件,DOWN 事件返回 false 之后,之后的 MOVE 事件和 UP 事件并没有触发。

设置为 false 之后,MOVE 事件和 UP 事件没有被执行。我们可以猜测一下,是不是被拦截了 ?事实是确实被拦截了
public abstract class ViewGroup extends View implements ViewParent, ViewManager {
    ...
    public boolean dispatchTouchEvent(MotionEvent ev) {
        ...
        if (dispatchTransformedTouchEvent(ev, false, child, idBitsToAssign)) {
        
        }
        ...
    }

    private boolean dispatchTransformedTouchEvent(MotionEvent event, boolean cancel,
            View child, int desiredPointerIdBits) {
        ...
        if (child == null) {
            handled = super.dispatchTouchEvent(event);
        } else {
            handled = child.dispatchTouchEvent(event);
        }
        ...
    }

    ...
}

因为触摸时候存在子 View 所以会调用 child.dispatchTouchEvent(event)。

public class View implements Drawable.Callback, KeyEvent.Callback,
        AccessibilityEventSource {
    ...
    public boolean dispatchTouchEvent(MotionEvent event) {
        ...
        //这里的onTouchEvent会调用到我们自定义的view中的onTouchEvent中去
        if (!result && onTouchEvent(event)) {
                result = true;
            }
        ...
        return result;
    }
    ...
    public boolean onTouchEvent(MotionEvent event) {
        ....
    }
}
因为触摸时候存在子 View 所以会调用 child.dispatchTouchEvent(event)
public class View implements Drawable.Callback, KeyEvent.Callback,
        AccessibilityEventSource {
    ...
    public boolean dispatchTouchEvent(MotionEvent event) {
        ...
        if (!result && onTouchEvent(event)) {
                result = true;
            }
        ...
        return result;
    }
    ...
    public boolean onTouchEvent(MotionEvent event) {
        ....
    }
}

如果 onTouchEvent 返回 super.onTouchEvent ( false ),那么 dispatchTouchEvent 返回的就是 false,dispatchTransformedTouchEvent 返回的也是 false。

接着看 ViewGroup

public abstract class ViewGroup extends View implements ViewParent, ViewManager {
    ...
    public boolean dispatchTouchEvent(MotionEvent ev) {
        ...
        if (dispatchTransformedTouchEvent(ev, false, child, idBitsToAssign)) {
            addTouchTarget(child, idBitsToAssign);
        }
        ...
    }

    private boolean dispatchTransformedTouchEvent(MotionEvent event, boolean cancel,
            View child, int desiredPointerIdBits) {
        ...
        if (child == null) {
            handled = super.dispatchTouchEvent(event);
        } else {
            handled = child.dispatchTouchEvent(event);
        }
        ...
    }
    
    private TouchTarget addTouchTarget(@NonNull View child, int pointerIdBits) {
        final TouchTarget target = TouchTarget.obtain(child, pointerIdBits);
        target.next = mFirstTouchTarget;
        mFirstTouchTarget = target;
        return target;
    }
    ...
}

dispatchTransformedTouchEvent 返回 false,那么 addTouchTarget 就不会被调用,mFirstTouchTarget 就为默认值 null。

当第二次执行 MOVE 事件后,dispatchTouchEvent 方法会被再次调用。

public abstract class ViewGroup extends View implements ViewParent, ViewManager {
    ...
    public boolean dispatchTouchEvent(MotionEvent ev) {
        ...
        final boolean intercepted;
        if (actionMasked == MotionEvent.ACTION_DOWN
                    || mFirstTouchTarget != null) {
            final boolean disallowIntercept = (mGroupFlags & FLAG_DISALLOW_INTERCEPT) != 0;
            if (!disallowIntercept) {
                intercepted = onInterceptTouchEvent(ev);
                ev.setAction(action); // restore action in case it was changed
            } else {
                intercepted = false;
            }
        } else {
            // There are no touch targets and this action is not an initial down
            // so this view group continues to intercept touches.
            intercepted = true;
        }
        
        if (!canceled && !intercepted) {
            if (dispatchTransformedTouchEvent(ev, false, child, idBitsToAssign)) {
            addTouchTarget(child, idBitsToAssign);
            }
        }
        ...
    }
    ...
}
intercepted 为 true 时,dispatchTransformedTouchEvent 就不会被执行,child.dispatchTouchEvent 不会被调用,View 的 onTouchEvent 就不会被执行。

所以想要 onTouchEvent 不断的执行,只有将返回值设置成 true。
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/807244.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Ansible-playbook(剧本)

Ansible-playbook(剧本) 一、playbook的构成 (1)Tasks:任务,即通过 task 调用 ansible 的模板将多个操作组织在一个 playbook 中运行(2)Variables:变量(3)Templates&am…

mybatis复杂环境搭建-多对一的处理-一对多的处理

复杂环境搭建: 1.1建表: CREATE table teacher( id int(10) not null, name varchar(30) default null, primary key(id) )engineInnoDB default charsetutf8mb3;INSERT INTO teacher (id, name) VALUES (1, 何老师);create table student( id int(10)…

用户端App自动化测试

一、自动化用例录制 1、Appium Inspctor 功能介绍 UI 分析录制用例元素查找测试Attcah 已有的 session云测试 2、用例录制 1)获取 app 的信息 2)配置待测应用 3、获取 app 的信息 1)app 入口,两种方式获取: * 通…

Linux系统中MySQL主从复制

本节主要学习了MySQL Replication概述,优点,复制类型,复制方式,复制过程和复制过程的限制,部署MySQL主从异步复制的流程及问题解决。 目录 一、MySQL Replication概述 1、优点 二、MySQL复制类型 1.异步复制&#…

#vue3报错 Cannot read properties of null (reading ‘isCE‘)#

场景:使用 npm 安装依赖包的时候,如如安装 npm i xlsx npm i file-saver 重新运行报错 Cannot read properties of null (reading isCE)# 解决办法: 使用的vite vue 在vite.config.ts添加如下配置: dedupe: [ vue ]

LeetCode使用最小花费爬楼梯(动态规划)

使用最小花费爬楼梯(动态规划) 题目描述算法流程(方法一)编程代码优化代码算法流程(方法二)编程代码代码优化 链接: 使用最小花费爬楼梯 题目描述 算法流程(方法一) 编程代码 class Solution { public:int minCostClimbingStair…

【雕爷学编程】Arduino动手做(104)---16X16点阵汉字屏模块2

37款传感器与执行器的提法,在网络上广泛流传,其实Arduino能够兼容的传感器模块肯定是不止这37种的。鉴于本人手头积累了一些传感器和执行器模块,依照实践出真知(一定要动手做)的理念,以学习和交流为目的&am…

8种工程设计优化问题Matlab代码:多种智能优化算法求解对比

目录 一、8种工程设计优化问题 二、8种工程设计优化问题部分问题介绍 2.1 焊接梁设计 2.2 拉力压缩弹簧设计 2.3 三杆衍架设计问题 2.4 压力容器设计 2.5 减速器设计问题 三、多种智能优化算法分别求解部分工程设计优化问题 3.1 焊接梁设计 3.2 拉力压缩弹簧设计 3.…

数据结构基础之二叉树

文章目录 二叉树性质二叉树分类遍历二叉树如何判断是否为完全二叉树 二叉树是树形结构的一个重要类型。许多实际问题抽象出来的数据结构往往是二叉树形式,即使是一般的树也能简单地转换为二叉树,而且二叉树的存储结构及其算法都较为简单,因此…

企业选择租用CRM还是一次性买断CRM?分别有哪些优势?

CRM是企业管理客户关系,提升销售业绩,实现业务增长的重要工具。市场上的CRM系统销售方式主要有两种——租用型和买断型。那么,租用CRM好还是一次性买断CRM好?本文将从以下几个方面进行分析: 1、什么是租用型CRM和买断…

shell中按照特定字符分割字符串,并且在切分后的每段内容后加上特定字符(串),然后再用特定字符拼接起来

文件中的内容&#xff0c;可以这么写&#xff1a; awk -F, -v OFS, {for(i1;i<‌NF;i){$i$i"_suffix"}}1 input.txt-F,&#xff1a;设置输入字段分隔符为逗号&#xff08;,&#xff09;&#xff0c;这将使awk按照逗号分割输入文本。-v OFS‘,’&#xff1a;设置输…

数据结构:栈和队列的实现和图解二者相互实现

文章目录 写在前面栈什么是栈栈的实现 队列什么是队列队列的实现 用队列实现栈用栈模拟队列 写在前面 栈和队列的实现依托的是顺序表和链表&#xff0c;如果对顺序表和链表不清楚是很难真正理解栈和队列的 下面为顺序表和链表的实现和图解讲解 手撕图解顺序表 手撕图解单链表 …

VMware虚拟机中配置静态IP

目录 环境原因基础概念VMnet网络IPV4网络私有地址范围Vmnet8的作用网路通信的过程解决方法1&#xff1a;修改k8s组件重新启动解决方法2&#xff1a;配置静态IP系统网卡设置设置虚拟机网关修改虚拟机网卡 环境 本机系统&#xff1a;windows11虚拟机系统&#xff1a;CentOS-7-x8…

【AutoGluon_03】保存模型并调用模型

在训练好autogluon模型之后&#xff0c;可以将模型进行保存。之后当有新的数据需要使用autogluon进行预测的时候&#xff0c;就可以直接加载原来训练好的模型进行训练。 import pandas as pd from sklearn.model_selection import train_test_split from autogluon.tabular im…

第九章:stack类

系列文章目录 文章目录 系列文章目录前言stack的介绍stack的使用成员函数使用stack 总结 前言 stack是容器适配器&#xff0c;底层封装了STL容器。 stack的介绍 stack的文档介绍 stack是一种容器适配器&#xff0c;专门用在具有后进先出操作的上下文环境中&#xff0c;其删除…

数字孪生技术从哪些方面为钢铁冶炼厂提高管理效率?

数字孪生系统是一种数字化技术&#xff0c;可以将物理世界中的实体对象、过程和数据进行数字化建模&#xff0c;以实现对其的可视化、模拟和优化。在炼铁生产管控中&#xff0c;数字孪生系统可以为以下方面提供支持&#xff1a; 炼铁生产线的可视化和控制&#xff1a;通过数字…

Web3 叙述交易所授权置换概念 编写transferFrom与approve函数

前文 Web3带着大家根据ERC-20文档编写自己的第一个代币solidity智能合约 中 我们通过ERC-20一种开发者设计的不成文规定 也将我们的代币开发的很像个样子了 我们打开 ERC-20文档 我们transfer后面的函数就是transferFrom 这个也是 一个账号 from 发送给另一个账号 to 数量 val…

指针初阶(1)

文章目录 目录1. 指针是什么2. 指针变量的类型2.1 指针变量-整数2.2 指针变量的解引用 3. 野指针3.1 野指针成因3.2 如何规避野指针 4. 指针运算4.1 指针-整数4.2 指针-指针4.3 指针的关系运算 附&#xff1a; 目录 指针是什么指针变量的类型野指针指针运算指针和数组二级指针…

redis集群设置

先下载redis数据库可以在一台机器上设置redis集群高可用 cd /etc/redis/ mkdir -p redis-cluster/redis600{1..6} for i in {1..6} do cp /opt/redis-5.0.7/redis.conf /etc/redis/redis-cluster/redis600$i cp /opt/redis-5.0.7/src/redis-cli /opt/redis-5.0.7/src/redis-s…

号外号外!首届开源 AI 游戏挑战赛圆满结束!

&#x1f917; 宝子们可以戳 阅读原文 查看文中所有的外部链接哟&#xff01; 北京时间 7 月 8 日到 7 月 10 日&#xff0c; 我们举办了首届开源 AI 游戏开发挑战赛。这是一场激动人心的赛事活动&#xff0c;游戏开发者在紧迫的 48 小时内使用 AI 创造、创新有创意的游戏。 本…