Android Touch事件分发过程详解

让我来详细讲解一下“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语言深入详解四大内存函数的使用

    C语言深入详解四大内存函数的使用攻略 1. malloc函数 malloc函数用于在堆内存中动态分配指定大小的内存空间,并返回一个指向该内存空间的指针。其函数原型如下: void* malloc(size_t size); 使用示例: #include <stdio.h> #include <stdlib.h> int main() …

    other 2023年8月2日
    00
  • tar 解压某个指定的文件或者文件夹

    tar 解压某个指定的文件或者文件夹 在Linux系统中,我们通常会使用tar命令来进行文件打包和解压缩,其中解压缩是一个常见的操作。本文就将介绍如何使用tar解压缩某个指定的文件或者文件夹。 前置条件 在进行解压缩的操作之前,需要确保电脑上已经安装了tar命令。 如果你使用的是Debian或Ubuntu这类的Linux发行版,你可以通过下面的命令安装tar…

    其他 2023年3月28日
    00
  • 基于WPF实现代码查看器控件

    如题所述,我们要实现一个基于WPF的代码查看器控件。以下是详细的攻略过程: 1.准备工作 在开始实现代码查看器控件之前,我们需要先准备好开发环境:Visual Studio 2019和.NET Framework 4.6.1(或更高版本)。这里推荐使用WPF应用程序模板来创建项目。 2.创建代码查看器控件 我们可以创建一个自定义的用户控件,将其命名为“Cod…

    other 2023年6月27日
    00
  • Android ServiceManager的启动和工作原理

    让我们开始。 1. Android ServiceManager简介 Android ServiceManager是Android系统中的一个重要的系统服务,它负责管理所有系统服务的启动和运行。 它主要有以下两个作用: 为其他系统服务提供注册、查找和获取服务的功能; 解决跨进程通信的问题。 2. ServiceManager启动 ServiceManager…

    other 2023年6月27日
    00
  • JS实现重新加载当前页面或者父页面的几种方法

    下面我将为你详细讲解JS实现重新加载当前页面或者父页面的几种方法。 方法一:使用location.reload()方法 简介 location.reload()方法可以重新加载当前页面,强制从服务器重新加载页面,而不是从浏览器缓存中加载。 用法 location.reload(); 示例 <!DOCTYPE html> <html> …

    other 2023年6月25日
    00
  • c语言undefined哪些

    c语言中定义未定义行为undefined哪些? 在C语言中,定义未定义行为(undefined behavior)是一个容易被误解和忽略的概念。在编写C语言程序时,忽略这些并不明确定义的行为可能会导致代码的不可预测和异常行为。 以下是一些C语言中定义为未定义行为的例子: 1. 访问未初始化的变量 在C语言中如果将未初始化的变量用作值,那么程序的行为是未定义的…

    其他 2023年3月28日
    00
  • java 获取服务器真实IP的实例

    下面是详细讲解 “java获取服务器真实IP的实例” 的攻略: 1. 理解IP地址 在讲解获取服务器真实IP之前,我们先来了解一下IP地址相关的知识。IP地址是Internet Protocol Address的缩写,即互联网协议地址,它是计算机在网络中的唯一标识符,类似于门牌号,用来唯一标识一个设备在网络中的位置。 IP地址一般分为IPv4和IPv6两种,…

    other 2023年6月27日
    00
  • c#截取字符串某个字符之后的字符

    当然,我很乐意为您提供有关“C#截取字符串某个字符之后的字符”的完整攻略。以下是详细的步骤和两个示例: 1 C#截取字符串某个字符之后的字符 在C#应用程序中,有时需要截取字符串某个字符之后的字符。以下是截取字符串某个字符之后的字符的方法: 1.1 使用Substring方法 您可以使用C#的Substring方法截取字符串某个字符之后的字符。以下是使用Su…

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