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日

相关文章

  • 怎样查看flutter项目使用的flutter版本号

    怎样查看Flutter项目使用的Flutter版本号 如果你正在使用Flutter开发应用程序,并且想知道该项目使用的Flutter版本号是多少,本文将向您介绍如何简单地查看Flutter版本号。 查看Flutter版本号的方法 1. 查看pubspec.yaml文件 在Flutter项目中,Flutter版本号通常在pubspec.yaml文件中声明。pu…

    其他 2023年3月28日
    00
  • python执行命令行

    以下是Python执行命令行的攻略,包含两个示例: 方法一:使用os模块 Python的os模块提供了执行命令行的功能。以下是一个使用os模块的示例: import os # 执行命令行 os.system("ls -l") 在这个示例中,我们使用os.system()函数执行了一个命令行命令“ls -l”,该命令会列出当前目录下的文件文…

    other 2023年5月6日
    00
  • Python的Django框架中URLconf相关的一些技巧整理

    下面是详细讲解“Python的Django框架中URLconf相关的一些技巧整理”的完整攻略。 简介 URLconf是Django框架中常用的模块之一,它可以将URL地址映射到相应的视图函数,并且可以通过正则表达式来匹配不同的URL地址。 在本文中,我们将会介绍一些Django框架中URLconf相关的最常用的技巧和用法。 常用语法 基本语法 Django框…

    other 2023年6月27日
    00
  • jshidden属性

    当然,我可以为您提供详细的“jshidden属性”的完整攻略,包括两个示例说明。 jshidden属性 在HTML中,jshidden属性用于隐藏元素使其在页面上不可见。在本教程中,将介绍jshidden属性的用法和示例。 语法 jshidden属性语法如下: <div jshidden></div> 示例 以下是两个示例,说明如何在…

    other 2023年5月7日
    00
  • ios:延时执行的三种方式

    iOS:延时执行的三种方式 在iOS开发中,我们经常需要延时执行一些代码,例如在用户点击按钮后延时执行某个操作,或者在某个时间点后执行某个操作。本文将提供一个完整攻略,介绍中延时执行的三种方式,并提供两个示例说明。 iOS中延时执行的三种方式 在iOS中可以使用以下三种方式现延时执行: NSTimer:NSTimer是iOS中的一个定时器类,可以用于定时执行…

    other 2023年5月8日
    00
  • FreeRTOS实时操作系统的任务概要讲解

    一、FreeRTOS实时操作系统概述 FreeRTOS是一个功能强大、灵活可靠且开源的实时操作系统。它支持多任务、多线程,并且可以运行于各种不同的嵌入式系统平台上。该系统具有以下特性: 内核位置独立,支持多种处理器架构; 轻量级设计,不需要特定硬件支持; 多任务支持,可以支持多个任务同时运行; 支持多种不同的调度算法; 支持不同类型的信号量、消息队列等同步机…

    other 2023年6月27日
    00
  • React Server Component混合式渲染问题详解

    针对“React Server Component混合式渲染问题详解”的完整攻略,我将按照以下几个方面进行详细讲解: React Server Component(RSC)是什么? RSC背景和优势 RSC的混合式渲染 两个示例说明 结论和总结 1. React Server Component(RSC)是什么? React Server Component…

    other 2023年6月26日
    00
  • Linux Shell脚本系列教程(四):使用函数添加环境变量

    首先,我们需要了解什么是Linux Shell函数以及如何使用它们。函数是Linux Shell编程中的一种语言结构,具有独立性和封装性,可以重复调用。函数可以将一组指令封装在一起,通过函数名来调用该组指令。在编写脚本时,使用函数可以简化代码,并提高代码的复用性。下面,我们将介绍如何使用函数来添加环境变量。 定义函数 定义函数的格式为: function_n…

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