android触摸事件流程(一)

对于android的触摸事件,一直以来都有点模糊,所以决定搞搞清楚.这里一共分三部分来解决这个问题:第一部分:触摸事件是如何起源的.第二部分:view是如何处理触摸事件的.第三部分:viewgroup是如何分发和处理触摸事件的.

这一次先看第一部分:触摸事件是如何起源的.

要理解这个问题,首先应该知道下面三点:

  • 每一个需要显示到手机上的视图最总都是通过WindowManager.addview()的方式来实现的,比如我们常用的activity/popwindow/状态栏/锁屏/来闹钟界面等!
  • 在WindowManager.addview()过程中实际上是调用WindowManagerGlobal.addView(),在这个方法里面是通过创建一个ViewRootImpl的对象,最后将需要显示的视图view加入到这个ViewRootImpl.也就是说显示的视图起源于ViewRootImpl.
  • 一个activity的视图起源于一个DecorView:DecorView其实是一个FrameLayout,我们在activity中通过setContentView()添加的显示view最终都是会加入这个DecorView里面的.

下面来看看触摸事件流程,看看触摸事件是如何流入视图的view的:

(1)每一个显示的窗口都是需要通过WindowManager.addview()来添加进去的,这个过程中会为这个显示的view创建一个该view与系统交互的ViewRootImpl.这里的触摸事件就是开始从ViewRootImpl来的.

(2)ViewRootImpl中定义了一个WindowInputEventReceiver来接收触摸事件.然后把触摸事件传递给mView.在activity中mView就是DecorView

(3)通过ViewRootImpl最后调用了view的dispatchPointerEvent(MotionEvent event).这样触摸事件就传递给了显示的view了

我们知道,对于activity来说,ViewRootImpl首先时把触摸事件传递给了DecorView的dispatchPointerEvent().下面来看看DecorView的dispatchPointerEvent源码:

public boolean dispatchTouchEvent(MotionEvent ev) {

final Callback cb = getCallback();

return cb != null && !isDestroyed() && mFeatureId < 0 ? cb.dispatchTouchEvent(ev)//会首先调用Callback的dispatchTouchEvent方法.

: super.dispatchTouchEvent(ev);

}

这里要知道这个Callback对象那里来的.来看看getCallback()的源码,在Window里面定义如下:

public final Callback getCallback() {

return mCallback;//看到了吧,其实很简单,直接返回mCallback即可.

}

那么mCallback是在何时赋值的呢?我们知道,创建一个activity就会为这个activity创建他的window,在activity中你会发现:原来activity已经implements了这个Callback

通过activity的代码你会发现其实在创建window的时候就给这个window的mCallback赋值了:

mWindow = PolicyManager.makeNewWindow(this);

mWindow.setCallback(this);//这里的this就是当前的activity

所以最终DecorView调用    dispatchTouchEvent会调用到activity的dispatchTouchEvent()方法.

(4)来看看activity的dispatchTouchEvent做来些什么:

public boolean dispatchTouchEvent(MotionEvent ev) {

if (ev.getAction() == MotionEvent.ACTION_DOWN) {

onUserInteraction();

}

if (getWindow().superDispatchTouchEvent(ev)) {//会调用Window的superDispatchTouchEvent方法,如果返回true,则结束,否则调用这个activity的onTouchEvent方法

return true;

}

return onTouchEvent(ev);

}

(5)所以来看看    Window的superDispatchTouchEvent方法.Window是一个虚类,其实现类是PhoneWindow

public boolean superDispatchTouchEvent(MotionEvent event) {

return mDecor.superDispatchTouchEvent(event);//实际上是调用DecorView的superDispatchTouchEvent方法

}

(6)来看看DecorView的superDispatchTouchEvent的

public boolean superDispatchTouchEvent(MotionEvent event) {

return super.dispatchTouchEvent(event);//看到了吧,最终还是调用了DecorView的dispatchTouchEvent方法

}

(7)综上所述:触摸事件从    ViewRootImpl开传递出来,最终会调用显示视图view的最父(最后面的/最老的)view的dispatchTouchEvent.如果返回false,就会调用activity的onTouchEvent()方法.

从上面的分析可以看出,触摸事件都是从dispatchTouchEvent开始的,所以要理解触摸事件的流程其实就要从view的dispatchTouchEvent开始.

时间: 2024-08-01 21:43:37

android触摸事件流程(一)的相关文章

Android触摸事件(一)-TouchEventHelper

文件夹 文件夹 概述 关于更新 2016-08-31 2016-06-20 关于单点触摸事件singleTouch 单击的两种方式 关于双击事件 双击事件的检測逻辑 双击事件触发的时机 关于多点触摸事件multiTouch 两点触摸中的移动事件 两点触摸事件的触发过程 两点触摸的事件 实现 变量定义 触摸事件流程 自己定义事件计时方案 自己定义事件触发区域 触摸事件处理规则 关于回调的方法 触摸事件处理源代码 双击事件的优化处理 怎样检測当次触摸事件的单击事件 怎样检測触发双击事件 辅助补充逻辑

iOS 和 Android 触摸事件传递

先看2篇文章,写得很好,都是咱们博客园的博文 ios 触摸事件传递 http://www.cnblogs.com/Quains/p/3369132.html android 触摸事件传递 http://www.cnblogs.com/superlcr/p/3946034.html 读完这2篇文章,可以发现ios和android对触摸事件的处理的大体思路是一致的,都是从根view开始,遍历检测子view,找到适合的view触发具体事件.2个平台都具备分发触摸事件,拦截触摸事件传递的机能. 下面盗用

一个demo让你彻底理解Android触摸事件的并发

注:本文涉及的demo的地址:https://github.com/absfree/TouchDispatch 1. 触摸动作及事件序列 (1)触摸事件的动作 触摸动作一共有三种:ACTION_DOWN.ACTION_MOVE.ACTION_UP.当用户手指接触屏幕时,便产生一个动作为ACTION_DOWN的触摸事件,此时若用户的手指立即离开屏幕,会产生一个动作为ACTION_UP的触摸事件:若用户手指接触屏幕后继续滑动,当滑动距离超过了系统中预定义的距离常数,则产生一个动作为ACTION_MO

Android触摸事件分发

Android的触摸分发机制和如何实现拦截 Android的触摸分发机制和如何实现拦截 前言 触摸事件的分发 情景分析 总结 前言 在自定义ViewGroup中,有时候需要实现触摸事件拦截,比如ListView下拉刷新就是典型的触摸事件拦截的例子.触摸事件拦截就是在触摸事件被parent view拦截,而不会分发给其child,即使触摸发生在该child身上.被拦截的事件会转到parent view的onTouchEvent方法中进行处理.但是这个交互过程还是挺复杂的,有多种情况,今天我们就来分

Android触摸事件分发机制

Android中的事件分为按键事件和触摸事件,这里对触摸事件进行阐述.Touch事件是由一个ACTION_DOWN,n个ACTION_MOVE,一个ACTION_UP组成onClick,onLongClick,onScroll等事件.Android中的控件都是继承View这个基类的,而控件分为两种:一种是继承View不能包含其他控件的控件:一种是继承ViewGroup可以包含其他控件的控件,暂且称为容器控件,比如ListView,GridView,LinearLayout等. 这里先对几个函数讲

Android触摸事件机制

前言 随着科学技术的发展,智能手机早已成为我们当代人身边必不可少的"伙伴"之一,堪比对象女友.每天我们对着手机重复的做着点击.滑动操作,而手机则随着我们的操作给我们展示她的精彩. - 废话到此结束. 看到这里,即使不是作为移动端码农的你也应该知道触摸事件对手机(经典键盘机除外)的重要性了. 什么是触摸事件 顾名思义,就是触摸手机屏幕后产生的事件.这时候请你拿出手机,点击屏幕中的某个按钮(不要松手),移动一段距离,松手. 这个过程一般会产生如下几个事件: 点击(Down)事件 移动(Mo

Android触摸事件

简介: 做了一个语音发送UI的小demo. 按下显示语音窗口,根据音量调节UI音量显示,上划至窗口显示取消发送. 原理: 1:获取什么事件来执行操作: 给Button添加setOnTouchListener事件,获得触摸事件,在滑动事件中得到当前显示控件的坐标,然后根据当前触摸位置与坐标进行判断来确定是否取消.在触摸离开的事件中来确定是否处理发送的请求. 2:更新音量值: 在线程中得到录音的音量大小,然后用handler发送到activity中进行UI更新. 详解事件: 通过public boo

Android触摸事件(四)-CropView裁剪工具的使用

目录 目录 概述 处理流程 裁剪方式 裁剪原理 裁剪流程 图片加载 图片绘制 获取屏幕的大小 计算图片绘制区域 绘制图片 计算裁剪框 绘制裁剪框 裁剪操作 计算实际裁剪区域 裁剪并保存图片 关于移动的限制 关于缩放的限制 使用方式 源码 裁剪类源码 裁剪View源码 接口源码 GitHub地址 概述 处理流程 裁剪方式 图片的裁剪方式有很多种,最常见的有两种吧. 但不管是哪什么类型的裁剪方式,至少需要处理的有以下两个点: 图片显示 裁剪框显示 裁剪方式的不同在于以上两部分的处理方式不同而不同.

Android触摸事件分发机制完全解析《一》

最近在做高德地图的时候,由于用户的要求,不得不用ScrollVew嵌套MapView,虽然很官方要求不建议这样做,但也迫于无奈- 魔高一尺,道高一丈.有什么事情事程序员不能解决的,如果有那就是解决两次. 鉴于用到了触摸事件,于是就来总结了Android的触摸事件机制. 首先当用户进行屏幕操作的时候,则有两种情况 一是按键事件 二是触摸事件 按键事件分为长按和点击事件,过于简单,这里不再进行总结. 触摸事件 触摸事件的组成: - 一个actionDown - n个actionMove - 一个ac