Android Touch事件分发过程详解

yizhihongxing

让我来详细讲解一下“Android Touch事件分发过程详解”的完整攻略。

一、Touch事件分发的概念及过程

在Android开发中,Touch事件是非常重要的一种事件类型。而Touch事件的分发过程也是我们需要了解的重要知识之一。Touch事件分发的过程可以简单地分为三个步骤:从根View开始往下递归地遍历View树,找到最合适的View来处理事件。

1. 步骤一:Touch事件的传递

当Touch事件发生时,它会被传递到当前界面的最外层View,即DecorView,然后再由DecorView传递到Activity的ContentView,再由ContentView传递到子View,一直往下传递,直到最后的目标View。

2. 步骤二:事件的分发

事件分发的过程是从外到内依次触发了三个方法:dispatchTouchEvent、onInterceptTouchEvent和onTouchEvent。

2.1 dispatchTouchEvent方法

ViewGroup会重写dispatchTouchEvent方法,同时它也是Touch事件的入口方法,它用来协调Touch事件的分发。在dispatchTouchEvent方法中,ViewGroup会调用onInterceptTouchEvent方法来判断是否拦截Touch事件。

2.2 onInterceptTouchEvent方法

在触发onInterceptTouchEvent方法时,会传入MotionEvent参数,即Touch事件。当ViewGroup的onInterceptTouchEvent方法返回true时,表示Touch事件被它拦截了,就不会再往下传递并进入View的onTouchEvent方法。如果返回false,则会继续往下传递。

2.3 onTouchEvent方法

当Touch事件被确定分发到某个View上时,该View会触发onTouchEvent方法来消费Touch事件。该方法的返回值为boolean类型,如果返回true,则表示该View消费了Touch事件,不再往下传递。如果返回false,则表示该View不消费Touch事件,会将Touch事件传递给它的父View,直到被某个View消费为止。

3. 步骤三:事件的处理

当Touch事件被一个View消费时,它就会被处理。View会根据Touch事件的类型,调用相应的方法来处理该事件,比如对于OnClickListener事件,可以通过调用View.performClick()方法来处理。

二、示例说明

为了更好地理解Touch事件分发的过程,下面来模拟两个场景,分别为ViewGroup和View的事件分发场景:

1. ViewGroup的事件分发

在一个LinearLayout中放置了4个Button。为了模拟事件分发过程,我们对LinearLayout和Button都重写了dispatchTouchEvent、onInterceptTouchEvent和onTouchEvent方法。代码如下:

public class MyLinearLayout extends LinearLayout {
    @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
        Log.i("MyLinearLayout", "dispatchTouchEvent");
        return super.dispatchTouchEvent(ev);
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        Log.i("MyLinearLayout", "onInterceptTouchEvent");
        return super.onInterceptTouchEvent(ev);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        Log.i("MyLinearLayout", "onTouchEvent");
        return super.onTouchEvent(event);
    }
}

public class MyButton extends Button {
    @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
        Log.i("MyButton", "dispatchTouchEvent");
        return super.dispatchTouchEvent(ev);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        Log.i("MyButton", "onTouchEvent");
        return super.onTouchEvent(event);
    }
}

当我们点击Button时,输出的日志如下:

MyLinearLayout: dispatchTouchEvent
MyLinearLayout: onInterceptTouchEvent
MyButton: dispatchTouchEvent
MyButton: onTouchEvent
MyButton: dispatchTouchEvent
MyButton: onTouchEvent
MyLinearLayout: onTouchEvent

从日志中可以看到,Touch事件首先被传递到了MyLinearLayout中,然后MyLinearLayout在onInterceptTouchEvent方法中将该事件拦截并消费,最终Touch事件在MyLinearLayout中被处理掉了。

2. View的事件分发

在一个TextView中,我们注册了一个OnTouchListener。代码如下:

textView.setOnTouchListener(new View.OnTouchListener() {
    @Override
    public boolean onTouch(View v, MotionEvent event) {
        Log.i("MyTextView", "onTouch");
        return false;
    }
});

当我们点击TextView时,输出的日志如下:

MyTextView: onTouch

从日志中可以看到,由于TextView并没有重写dispatchTouchEvent、onInterceptTouchEvent和onTouchEvent方法,因此Touch事件并不会在TextView中被分发处理。同时,由于OnTouchListener的返回值为false,表示未处理Touch事件,该Touch事件会继续往下传递并最终被父View处理。最终,Touch事件在View中被处理掉了。

总结

通过这两个示例,我们可以更好地理解Touch事件分发的过程及机制。对于开发中遇到的Touch事件相关问题,我们可以更加快速、准确地排查问题。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Android Touch事件分发过程详解 - Python技术站

(0)
上一篇 2023年6月27日
下一篇 2023年6月27日

相关文章

  • 简单谈谈C++ 头文件系列之(iosfwd)

    当我们使用C++编写程序时,有时候需要使用C++标准库的头文件,例如iostream、fstream等等。而在使用这些头文件时,我们通常会先包含iostream或fstream等文件,但是这些文件又包含了大量的定义和声明,这样在编译时会比较慢,因此,我们可以使用头文件iosfwd来替代这些头文件。 iosfwd头文件包含了一些标准库的前置声明,可以将一些标准…

    other 2023年6月27日
    00
  • java中lombok的@Data引发问题详解

    Java中Lombok的@Data引发问题详解 引言 Lombok是一个Java库,可以自动为Java类生成一些标准的方法(如 equals(), hashCode(), toString() 等),以减少样板代码的编写。其中,@Data是Lombok中一种常用的注解,作用是自动生成JavaBean中的getter/setter方法、hashCode/equ…

    other 2023年6月27日
    00
  • 怎么安装nslookup

    nslookup是一种用于查询DNS记录的命令行工具。如果您需要使用nslookup,可以按照以下步骤进行安装。以下是如何安装nslookup的完整攻略,包含两个示例说明。 步骤一:打开终端 在Windows上,打开命令提示符。在macOS或Linux上,打开终端。 步骤二:安装nslookup 在Windows上,nslookup是默认安装的。在macOS…

    other 2023年5月9日
    00
  • C语言基础之malloc和free函数详解

    C语言基础之malloc和free函数详解 在C语言中,malloc和free是用于动态内存分配和释放的两个重要函数。本文将详细讲解它们的使用方法和注意事项。 1. malloc函数 malloc函数用于在运行时动态分配内存空间。它的函数原型如下: void* malloc(size_t size); size参数表示要分配的内存空间的字节数。 malloc…

    other 2023年8月1日
    00
  • sqlserver游标基本概念到生命周期的详细学习(sql游标读取)

    SQL Server游标可以用于按照一定条件遍历和读取数据集合中的每一行数据,常用于在存储过程或触发器中对数据执行复杂的逻辑操作。下面详细介绍SQL Server游标的基本概念,并以示例说明游标的使用,步骤如下: 1. 游标的基本概念 游标定义:游标是对数据集合中数据行的逐行处理。通过游标的方式,可以对数据集合中的每一行数据进行操作,并可以记录当前操作的位置…

    other 2023年6月27日
    00
  • 虚拟主机下实现多域名绑定不同的子目录的方法

    首先,我们需要了解什么是虚拟主机和多域名绑定。 虚拟主机是在一台物理服务器上,通过技术手段将多个网站分别托管在不同的虚拟主机上,并通过不同的域名访问这些网站的服务。虚拟主机一般通过HTTP服务器软件来实现,例如Apache、Nginx等。 多域名绑定是指在同一台服务器上,通过DNS解析将多个域名解析到同一个IP地址上,并通过HTTP服务器软件将这些域名所对应…

    other 2023年6月27日
    00
  • Python paramiko使用方法代码汇总

    Python paramiko使用方法代码汇总 什么是paramiko? paramiko 是一个用于进行远程服务器操作的 Python 库,它采用了传统的SSH协议。通过 paramiko 可以实现 SSH2 协议的认证、加密、SSH 会话和 SFTP 协议等。 install 可以直接使用pip命令安装: pip install paramiko 使用方…

    other 2023年6月27日
    00
  • 解决python 读取npy文件太大不能完全显示的问题

    当我们使用Python读取大型np.array文件(npy格式)时,有时我们可能会遇到读取后无法完全显示的问题。这通常是由于数组过大导致的内存限制,为了解决这个问题,以下是解决方法的完整攻略: 分段读取 当数组太大时,我们可以分段读取。这种方法使用Python迭代器来访问数组的各个部分,并将它们分别存储在内存中。我们可以使用以下代码来读取大型npy文件: i…

    other 2023年6月27日
    00
合作推广
合作推广
分享本页
返回顶部