Android TouchEvent事件传递机制初识

android源码阅读 专栏收录该内容
11 篇文章 0 订阅

本期三篇文章目录(可点击跳转)

一. Android TouchEvent事件传递机制初识

二. android点击事件传递源码讲解(ViewGroup)


Android TouchEvent事件传递机制在android应用开发中很常见,但是很多人不了解,现自我总结如下:

1.触发OnTouch事件的时候的三个方法:

在触发OnTouch事件的时候Android的GroupView会调用如下三个函数:
public boolean dispatchTouchEvent(MotionEvent ev) //用于事件的分发
public boolean onInterceptTouchEvent(MotionEvent ev) // 用于事件的拦截
public boolean onTouchEvent(MotionEvent ev) //处理事件

2.控件中包含哪些方法

在Android中,有一类控件是中还可以包含其他的子控件,这类控件是继承于ViewGroup类,例如:ListView, Gallery, GridView,FrameLayout、LinearLayout。
还有一类控件是不能再包含子控件,例如:Button、TextView、EditText。

这些控件中分别拥有如下的函数


Activity类: Activity -------------包含方法:
dispatchTouchEvent(); onTouchEvent();

View容器(ViewGroup的子类):比如FrameLayout、LinearLayout……ListView、ScrollVIew……这些控件 -----------------包含方法:
dispatchTouchEvent(); onInterceptTouchEvent(); onTouchEvent();

View控件(非ViewGroup子类):比如Button、TextView、EditText……这些控件---------------- 包含方法:
dispatchTouchEvent(); onTouchEvent();


3.这三个方法的具体作用

1)dispatchTouchEvent()
用来分派事件。
其中调用了onInterceptTouchEvent()和onTouchEvent(),一般不重写该方法

2)onInterceptTouchEvent()
用来拦截事件。--------->父View向子View传递
ViewGroup类中的源码默认返回false,表示不拦截该事件,事件将向下传递(传递给其子View),如果子View不是ViewGroup类的控件,则传递给它自己onTouchEvent去处理;
若重写该方法,返回true则表示拦截,事件将终止向下传递,事件由当前ViewGroup类来处理,就是调用该类的onTouchEvent()方法。

3)onTouchEvent()
用来处理事件。--------->子View向父View传递
返回true则表示事件已经被处理,事件将终止向上传递(父View);
返回false表示事件没有被处理,则把事件传递给其父View的onTouchEvent()方法来处理

注意点:ACTION_MOVE或者ACTION_UP发生的前提是该控件一定曾经发生了ACTION_DOWN,如果你没有消费ACTION_DOWN,那么系统会认为ACTION_DOWN没有发生过,所以ACTION_MOVE或者ACTION_UP就不能被捕获。也就是说onTouchEvent均返回false,也就是说事件始终没有被消费,那后续事件(ACTION_DOWN的ACTION_MOVE或者ACTION_UP)不会触发,后面demo中会提到。

4.示例
页面布局如下

<?xml version="1.0" encoding="utf-8"?>
<focus.teach.toucheventdemo.LinearLayoutOne xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <focus.teach.toucheventdemo.LinearLayoutTwo
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <focus.teach.toucheventdemo.MyTextView
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:text="ddddd" />
    </focus.teach.toucheventdemo.LinearLayoutTwo>

</focus.teach.toucheventdemo.LinearLayoutOne>

很简单的三层,下面通过控制上面三个方法的返回,看事件的传递。
1)LinearLayoutOne,LinearLayoutTwo,MyTextView 的dispatchTouchEvent,onInterceptTouchEvent(MyTextView没有此方法),onTouchEvent均返回false,也就是说事件始终没有被处理,也就是抛给外层的activity的ontouchEvent去处理了,那后续事件(ACTION_DOWN的ACTION_MOVE或者ACTION_UP)也都不会触发。Log信息如下:


05-13 13:04:19.521 32126-32126/focus.teach.toucheventdemo I/focus.teach.toucheventdemo.LinearLayoutOne: LinearLayoutOne---dispatchTouchEvent---ACTION_DOWN
05-13 13:04:19.521 32126-32126/focus.teach.toucheventdemo I/focus.teach.toucheventdemo.LinearLayoutOne: LinearLayoutOne---onInterceptTouchEvent---ACTION_DOWN
05-13 13:04:19.521 32126-32126/focus.teach.toucheventdemo I/focus.teach.toucheventdemo.LinearLayoutTwo: LinearLayoutTwo---dispatchTouchEvent---ACTION_DOWN
05-13 13:04:19.521 32126-32126/focus.teach.toucheventdemo I/focus.teach.toucheventdemo.LinearLayoutTwo: LinearLayoutTwo---onInterceptTouchEvent---ACTION_DOWN
05-13 13:04:19.521 32126-32126/focus.teach.toucheventdemo I/focus.teach.toucheventdemo.MyTextView: MyTextView---dispatchTouchEvent---ACTION_DOWN
05-13 13:04:19.521 32126-32126/focus.teach.toucheventdemo I/focus.teach.toucheventdemo.MyTextView: MyTextView---onTouchEvent---ACTION_DOWN
05-13 13:04:19.522 32126-32126/focus.teach.toucheventdemo I/focus.teach.toucheventdemo.LinearLayoutTwo: LinearLayoutTwo---onTouchEvent---ACTION_DOWN
05-13 13:04:19.522 32126-32126/focus.teach.toucheventdemo I/focus.teach.toucheventdemo.LinearLayoutOne: LinearLayoutOne---onTouchEvent---ACTION_DOWN
05-13 13:04:19.522 32126-32126/focus.teach.toucheventdemo I/focus.teach.toucheventdemo.MainActivity: MainActivity---onTouchEvent---ACTION_DOWN
05-13 13:04:19.532 32126-32126/focus.teach.toucheventdemo I/focus.teach.toucheventdemo.MainActivity: MainActivity---onTouchEvent---ACTION_MOVE
05-13 13:04:19.999 32126-32126/focus.teach.toucheventdemo I/focus.teach.toucheventdemo.MainActivity: MainActivity---onTouchEvent---ACTION_MOVE
05-13 13:04:20.015 32126-32126/focus.teach.toucheventdemo I/focus.teach.toucheventdemo.MainActivity: MainActivity---onTouchEvent---ACTION_MOVE
05-13 13:04:20.048 32126-32126/focus.teach.toucheventdemo I/focus.teach.toucheventdemo.MainActivity: MainActivity---onTouchEvent---ACTION_MOVE
05-13 13:04:20.056 32126-32126/focus.teach.toucheventdemo I/focus.teach.toucheventdemo.MainActivity: MainActivity---onTouchEvent---ACTION_UP

运行结论:LinearLayoutOne,LinearLayoutTwo,MyTextView都只处理了ACTION_DOWN,其余的TouchEvent被外层的Activity处理了

2)LinearLayoutOne,MyTextView 的dispatchTouchEvent,onInterceptTouchEvent(MyTextView没有此方法),onTouchEvent均返回false,LinearLayoutTwo onInterceptTouchEvent返回true,此时ACTION_DOWN应该传递到LinearLayoutTwo 的onTouchEvent,而不是像下传递到MyTextView 的onTouchEvent。同样,onTouchEvent均返回false,也就是说事件始终没有被处理,也就是抛给外层的activity的ontouchEvent去处理了,那后续事件(ACTION_DOWN的ACTION_MOVE或者ACTION_UP)也都不会触发。Log信息如下:

05-13 13:19:22.413 14442-14442/focus.teach.toucheventdemo I/focus.teach.toucheventdemo.LinearLayoutOne: LinearLayoutOne---dispatchTouchEvent---ACTION_DOWN
05-13 13:19:22.413 14442-14442/focus.teach.toucheventdemo I/focus.teach.toucheventdemo.LinearLayoutOne: LinearLayoutOne---onInterceptTouchEvent---ACTION_DOWN
05-13 13:19:22.413 14442-14442/focus.teach.toucheventdemo I/focus.teach.toucheventdemo.LinearLayoutTwo: LinearLayoutTwo---dispatchTouchEvent---ACTION_DOWN
05-13 13:19:22.413 14442-14442/focus.teach.toucheventdemo I/focus.teach.toucheventdemo.LinearLayoutTwo: LinearLayoutTwo---onInterceptTouchEvent---ACTION_DOWN
05-13 13:19:22.414 14442-14442/focus.teach.toucheventdemo I/focus.teach.toucheventdemo.LinearLayoutTwo: LinearLayoutTwo---onTouchEvent---ACTION_DOWN
05-13 13:19:22.415 14442-14442/focus.teach.toucheventdemo I/focus.teach.toucheventdemo.LinearLayoutOne: LinearLayoutOne---onTouchEvent---ACTION_DOWN
05-13 13:19:22.416 14442-14442/focus.teach.toucheventdemo I/focus.teach.toucheventdemo.MainActivity: MainActivity---onTouchEvent---ACTION_DOWN
05-13 13:19:22.434 14442-14442/focus.teach.toucheventdemo I/focus.teach.toucheventdemo.MainActivity: MainActivity---onTouchEvent---ACTION_MOVE
05-13 13:19:22.503 14442-14442/focus.teach.toucheventdemo I/focus.teach.toucheventdemo.MainActivity: MainActivity---onTouchEvent---ACTION_MOVE
05-13 13:19:22.518 14442-14442/focus.teach.toucheventdemo I/focus.teach.toucheventdemo.MainActivity: MainActivity---onTouchEvent---ACTION_MOVE
05-13 13:19:22.552 14442-14442/focus.teach.toucheventdemo I/focus.teach.toucheventdemo.MainActivity: MainActivity---onTouchEvent---ACTION_MOVE
05-13 13:19:22.567 14442-14442/focus.teach.toucheventdemo I/focus.teach.toucheventdemo.MainActivity: MainActivity---onTouchEvent---ACTION_MOVE
05-13 13:19:22.569 14442-14442/focus.teach.toucheventdemo I/focus.teach.toucheventdemo.MainActivity: MainActivity---onTouchEvent---ACTION_UP

运行结论:LinearLayoutOne,LinearLayoutTwo都只处理了ACTION_DOWN,其余的TouchEvent被外层的Activity处理了

其他的几种情况,可以自己去测试。

5.逻辑抽象
拿上面第二个示例,画出对应的逻辑图,如下所示:
在这里插入图片描述

demo下载地址:
http://download.csdn.net/detail/dfskhgalshgkajghljgh/9525803

其他的逻辑图就不画了,有问题欢迎提出来。


如有错误欢迎指出来,一起学习。
在这里插入图片描述

  • 0
    点赞
  • 0
    评论
  • 0
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

相关推荐
<p style="color:#666666;"> <span style="font-size:14px;">本门课程重实战,将基础知识拆解到项目里,让你在项目情境里学知识。</span> </p> <p style="color:#666666;"> <span style="font-size:14px;">这样的学习方式能让你保持兴趣、充满动力,时刻知道学的东西能用在哪、能怎么用。</span> </p> <p style="color:#666666;"> <span style="font-size:14px;">平时不明白的知识点,放在项目里去理解就恍然大悟了。</span> </p> <p style="color:#666666;"> <span></span> </p> <p style="color:#666666;"> <span style="font-size:14px;"> </span> </p> <p style="color:#666666;"> <span style="color:#FF0000;font-size:14px;"><strong>一、融汇贯通</strong></span> </p> <p style="color:#666666;"> <span style="font-size:14px;">本视频采用了前后端分离的开发模式,前端使用Vue.js+Element UI实现了Web页面的呈现,后端使用Python 的Django框架实现了数据访问的接口,前端通过Axios访问后端接口获得数据。在学习完本章节后,真正理解前后端的各自承担的工作。</span> </p> <p style="color:#666666;"> <span style="font-size:14px;"> </span> </p> <p style="color:#666666;"> <span style="color:#FF0000;font-size:14px;"><strong>二、贴近实战</strong></span> </p> <p style="color:#666666;"> <span style="font-size:14px;">本系列课程为练手项目实战:学生管理系统v4.0的开发,项目包含了如下几个内容:项目的总体介绍、基本功能的演示、Vuejs的初始化、Element UI的使用、在Django中实现针对数据的增删改查的接口、在Vuejs中实现前端增删改查的调用、实现文件的上传、实现表格的分页、实现导出数据到Excel、实现通过Excel导入数据、实现针对表格的批量化操作等等,所有的功能都通过演示完成、贴近了实战</span> </p> <p style="color:#666666;"> <span style="font-size:14px;"> </span> </p> <p style="color:#666666;"> <span style="color:#FF0000;font-size:14px;"><strong>三、课程亮点</strong></span> </p> <p style="color:#666666;"> <span style="font-size:14px;">在本案例中,最大的亮点在于前后端做了分离,真正理解前后端的各自承担的工作。前端如何和后端交互</span> </p> <p style="color:#666666;"> <span style="font-size:14px;"> </span> </p> <p style="color:#666666;"> <span style="color:#FF0000;font-size:14px;"><strong>适合人群:</strong></span> </p> <p style="color:#666666;"> <span style="font-size:14px;">1、有Python语言基础、web前端基础,想要深入学习Python Web框架的朋友;</span> </p> <p style="color:#666666;"> <span style="font-size:14px;">2、有Django基础,但是想学习企业级项目实战的朋友;</span> </p> <p style="color:#666666;"> <span style="font-size:14px;">3、有MySQL数据库基础的朋友</span> </p> <p style="color:#666666;"> <span style="font-size:14px;"> </span> </p> <p style="color:#666666;"> <span style="font-size:14px;"><img alt="" src="https://img-bss.csdnimg.cn/202009070752197496.png" /><br /> </span> </p> <p style="color:#666666;"> <span style="font-size:14px;"><br /> </span> </p>
©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值