Android触屏事件流[通俗易懂]

Android触屏事件流[通俗易懂]一次触屏事件分为三个动作ACTION_DOWN,ACTION_MOVE和ACTION_UP。其中ACTION_DOWN和ACTION_UP在一次触屏事件中只会触发一次,ACTION_MOVE可能触发任意次(包括0次)。主要响应触屏的组件有两种,一种是可以包含子元素的(ViewGroup比如LinearLayout),另一种是不能包含子元素的View(最底层的View比

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE使用 1年只要46元 售后保障 童叟无欺

一次触屏事件分为三个动作
ACTION_DOWN, ACTION_MOVE 和 ACTION_UP。
其中ACTION_DOWN和ACTION_UP在一次触屏事件中只会触发一次,ACTION_MOVE可能触发任意次(包括0次)。
主要响应触屏的组件有两种,一种是可以包含子元素的(ViewGroup比如LinearLayout),另一种是不能包含子元素的View(最底层的View比如Button)。
当一个触屏事件产生时,正两者的响应方法有一个主要的区别就是LinearLayout有onInterceptTouchEvent方法,而Button没有onInterceptTouchEvent方法。
1 ViewGroup(比如LinearLayout)
2 boolean dispatchTouchEvent(MotionEvent event)
3 boolean onInterceptTouchEvent(MotionEvent event)
4 boolean onTouchEvent(MotionEvent event)
5  
6 View(比如Button)
7 boolean dispatchTouchEvent(MotionEvent event)
8 boolean onTouchEvent(MotionEvent event)


总的来说,dispatchTouchEvent决定处理什么,onInterceptTouchEvent决定谁来处理,onTouchEvent决定怎么处理。所以对于Button来谁,没有小弟,自然不存在决定谁来处理的问题,故没有onInterceptTouchEvent方法

下面具体说一下这三个函数的主要作用:
dispatchTouchEvent决定处理什么,看名字就知道是事件分发,初看我还以为是分发到子元素呢,原来不是直接到子元素。其实更好的理解是这是一个过滤方法。此方法的主要作用是决定相应事件的类型。
假如dispatchTouchEvent返回false,那么在响应了ACTION_DOWN之后,后续的ACTION_MOVE和ACTION_UP均忽略,因此ACTION_MOVE和ACTION_UP永远不会有得到处理的机会。
假如dispatchTouchEvent,那么后续的ACTION_MOVE和ACTION_UP均被接受,可以被其他方法响应。

特别注意,如果在这一步的dispatchTouchEvent中没有调用super.dispatchTouchEvent(event),那么事件就到此为止,被终结了。此时此刻只有dispatchTouchEvent会响应事件,另外两个方法根本没有机会来响应事件。并且,事件不会传递到子元素中。

onInterceptTouchEvent,主要决定谁来处理(即是否拦截事件)。只要在dispatchTouchEvent中调用了super.dispatchTouchEvent(event)那么,事件(event)会被交给onInterceptTouchEvent去处理。注意,这里事件(event)是否会调用onInterceptTouchEvent与dispatchTouchEvent的返回值是true还是false无关。再次强调,dispatchTouchEvent只决定处理什么,并不能指定谁来调用。
假如onInterceptTouchEvent返回false,将事件(event)交自己的子元素处理(此时事件流是从外到内,从父元素到子元素)。
假如onInterceptTouchEvent返回true,将事件(event)交给自己的onTouchEvent来处理,并且如果有后续的ACTION_MOVE和ACTION_UP(前一步dispatchTouchEvent中返回true)的话,将不再调用onInterceptTouchEvent,直接将事件传递给自己的onTouchEvent来处理。

注意上一步,在onInterceptTouchEvent返回true的情况下,onTouchEvent将获得事件并进行具体的处理。
假如onTouchEvent返回false,将事件(event)交父元素处理,(注意在这一步,事件流反向了,此时事件流是从内到外,从子元素到父元素)。
假如onTouchEvent返回true,本次事件(event)就到此为止,被终结了。

对照上面的说法,下面给出实例说明:
01 public class MyLinearLayout1 extends LinearLayout{
02  
03     private String TAG = "第一层MyLinearLayout";
04      
05     public MyLinearLayout1(Context context) {
06         super(context);
07         this.setBackgroundColor(Color.WHITE);
08     }
09     public void setTagString(String tag){
10         TAG = tag;
11     }
12      
13     @Override
14     public boolean dispatchTouchEvent(MotionEvent event){
15         if(MotionEvent.ACTION_DOWN == event.getAction()){
16             Log.v(TAG + "dispatchTouchEvent:""ACTION_DOWN");
17         }else if(MotionEvent.ACTION_MOVE == event.getAction()){
18             Log.v(TAG + "dispatchTouchEvent:""ACTION_MOVE");
19         }else{
20             Log.v(TAG + "dispatchTouchEvent:""ACTION_UP");
21         }
22         <span style="color:#e53333;">//super.dispatchTouchEvent(event);</span>      return true;
23     }
24  
25     @Override
26     public boolean onInterceptTouchEvent(MotionEvent event){
super.onInterceptTouchEvent
27  
28         if(MotionEvent.ACTION_DOWN == event.getAction()){
29             Log.v(TAG + "onInterceptTouchEvent:""ACTION_DOWN");
30         }else if(MotionEvent.ACTION_MOVE == event.getAction()){
31             Log.v(TAG + "onInterceptTouchEvent:""ACTION_MOVE");
32         }else{
33             Log.v(TAG + "onInterceptTouchEvent:""ACTION_UP");
34         }
35         return true;
36     }
37      
38     @Override
39     public boolean onTouchEvent(MotionEvent event){
super.onTouchEvent(event)
40         if(MotionEvent.ACTION_DOWN == event.getAction()){
41             Log.v(TAG + "onTouchEvent:""ACTION_DOWN");
42         }else if(MotionEvent.ACTION_MOVE == event.getAction()){
43             Log.v(TAG + "onTouchEvent:""ACTION_MOVE");
44         }else{
45             Log.v(TAG + "onTouchEvent:""ACTION_UP");
46         }
47          
48         return true;
49     }
50 }

此时没有调用super.dispatchTouchEvent(event),所以事件没有机会得到其他的处理。

打印信息:
1 第一层MyLinearLayoutdispatchTouchEvent:(460): ACTION_DOWN
2 第一层MyLinearLayoutdispatchTouchEvent:(460): ACTION_UP

如果将上面boolean dispatchTouchEvent(MotionEvent event)的返回值修改为false,那么按照前面说的,MyLinearLayout1在响应了ACTION_DOWN之后,不会再响应本次触屏操作的其他事件。所以此时的打印结果是:

1 第一层MyLinearLayoutdispatchTouchEvent:(460): ACTION_DOWN

可以看到,ACTION_UP没有被响应,因为本事件被忽略了。


现在,将super.dispatchTouchEvent(event)的注释去掉,注意,现在的boolean dispatchTouchEvent(MotionEvent event)变成下面这样:
01     @Override
02     public boolean dispatchTouchEvent(MotionEvent event){
03         if(MotionEvent.ACTION_DOWN == event.getAction()){
04             Log.v(TAG + "dispatchTouchEvent:""ACTION_DOWN");
05         }else if(MotionEvent.ACTION_MOVE == event.getAction()){
06             Log.v(TAG + "dispatchTouchEvent:""ACTION_MOVE");
07         }else{
08             Log.v(TAG + "dispatchTouchEvent:""ACTION_UP");
09         }<p>        <span style="color:#e53333;">super.dispatchTouchEvent(event);//去掉注释了</span></p>
10 <p>         return true;</p>
11     }

打印信息:

1 第一层MyLinearLayout ACTION_DOWN:(783): ACTION_DOWN
2 第一层MyLinearLayout onInterceptTouchEvent:(783): ACTION_DOWN
3 第一层MyLinearLayout onTouchEvent:(783): ACTION_DOWN
4 第一层MyLinearLayout dispatchTouchEvent:(783): ACTION_UP
5 第一层MyLinearLayout onTouchEvent:(783): ACTION_UP

具体顺序为下:

1 ACTION_DOWN:ACTION_DOWN——>onInterceptTouchEvent——>onTouchEvent
2 ACTION_UP:ACTION_DOWN——>onTouchEvent

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/195353.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • dlsym用法_DLSS模式

    dlsym用法_DLSS模式dlsymdlsym,dlvsym-从一个动态链接库或者可执行文件中获取到符号地址。用法#include<dlfcn.h>void*dlsym(void*handle,constchar*symbol);#define_GNU_SOURCE#include<dlfcn.h>void*dlvsym(void*handle,char*symbol,char*version);Linkwith-ldl.详解函数dlsym()的第

    2022年10月23日
    0
  • c语言图书管理系统案例实训_c语言实现图书馆系统

    c语言图书管理系统案例实训_c语言实现图书馆系统本次案例需要三个文件来运行分别是StuManage.h//头文件、StuManage.c//函数定义和main.c//测试文件#include<stdio.h>#ifndefSTUMANA_STUMANA_H#defineSTUMANA_STUMANA_Htypedefstructbook{charbnum[10];charbname[30];charbauthor[20];charbclassfy[10];floatbprice;.

    2022年10月9日
    1
  • 漏洞扫描工具汇总「建议收藏」

    漏洞扫描工具汇总「建议收藏」漏洞扫描器可以快速帮助我们发现漏洞,如SQL注入漏洞、CSRF、缓冲区溢出等。下面就介绍几种常用的漏洞扫描工具。Fortify代码审计工具FortifySCA(FortifyStaticCodeAnalyzer),一款软件代码安全测试工具,提供静态源码扫描能力,包含了五大引擎分析系统:语义、结构、数据流、控制流、配置流。分析的过程中与特有的软件安全漏洞规则集进行全面的匹配、查找,从而将源代码中存在的安全漏洞扫描出来,并生成报告。BurpSuiteAWVSAppScanDependen

    2022年9月13日
    0
  • 如何使用PathFileExists[通俗易懂]

    如何使用PathFileExists[通俗易懂]#pragmacomment(lib,”shlwapi.lib”)

    2022年7月12日
    15
  • java输出数组的方法_java怎样输出数组中的所有元素

    java输出数组的方法_java怎样输出数组中的所有元素文章目录数组的输出的三种方式一维数组:1.传统的for循环方式2.foreach循环3.利用Array类中的toString方法二维数组:1.传统的for循环方式2.foreach循环3.利用Array类中的toString方法数组的输出的三种方式一维数组:定义一个数组int[]array={1,2,3,4,5};1.传统的for循环方式for(inti=0;i<array.length;i++){System.out.println(array

    2022年10月11日
    0
  • 安装office2016时弹出microsoft setup bootstrapper已停止工作的解决办法

    安装office2016时弹出microsoft setup bootstrapper已停止工作的解决办法安装office2016时安装进度条走到最后又回滚,弹出microsoftsetupbootstrapper已停止工作,最后“安装出错”经过了1天的试尽了各种控制面板卸载、文件夹删除、office注册表删除等方法,最后用了以下方法才终于解决。希望没试过我这个方法的朋友们先试下这个方法。(⊙o⊙)…确认启动WindowsEventLog这个服务项。Windows系统的服务打开方…

    2022年7月20日
    37

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号