android触摸事件流程(一)
来源:互联网 发布:查看淘宝店铺数据 编辑:程序博客网 时间:2024/06/07 18:40
对于android的触摸事件,一直以来都有点模糊,所以决定搞搞清楚.这里一共分三部分来解决这个问题:第一部分:触摸事件是如何起源的.第二部分:view是如何处理触摸事件的.第三部分:viewgroup是如何分发和处理触摸事件的.
这一次先看第一部分:触摸事件是如何起源的.
(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方法
}
这一次先看第一部分:触摸事件是如何起源的.
要理解这个问题,首先应该知道下面三点:
- 每一个需要显示到手机上的视图最总都是通过WindowManager.addview()的方式来实现的,比如我们常用的activity/popwindow/状态栏/锁屏/来闹钟界面等!
- 在WindowManager.addview()过程中实际上是调用WindowManagerGlobal.addView(),在这个方法里面是通过创建一个ViewRootImpl的对象,最后将需要显示的视图view加入到这个ViewRootImpl.也就是说显示的视图起源于ViewRootImpl.
- 一个activity的视图起源于一个DecorView:DecorView其实是一个FrameLayout,我们在activity中通过setContentView()添加的显示view最终都是会加入这个DecorView里面的.
(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()方法.
0 0
- android触摸事件流程(一)
- android触摸事件处理流程
- android触摸事件处理流程
- Android触摸事件处理流程
- Android触摸事件(一)-TouchEventHelper
- android 触摸事件传递(一)
- (2)android触摸事件处理流程
- Android 触摸事件传递流程解析
- android 触摸事件处理流程说明
- android(五)、 ViewRoot触摸事件流程
- Android 触摸事件传递流程解析
- Android View系统源码分析(一)——概述&触摸事件总体处理流程
- android 触摸事件、点击事件的区别,执行流程
- android 触摸事件、点击事件的区别,执行流程
- Android 触摸事件机制(一) 简介
- Android View触摸事件传递机制 一
- Android源码解析(三十)-->触摸事件分发流程
- Android O: 触摸事件传递流程源码分析(上)
- mongoDB报错Cannot find module '../build/Release/bson'
- iOS 项目中用到的一些 iOS 开源库和第三方组件
- 关于后盾网yii框架的学习小结(10)--使用AR类的增删改查
- jQuery开发之动画二
- 传智播客PHP学科进驻上海,给华东IT圈报喜
- android触摸事件流程(一)
- android 去掉顶部状态栏
- jquery计时器timer
- 基于python:opencv简单图片操作
- POJ 1008 && HDU 1444 Maya Calendar(历法)
- js常用判断
- HTMl5的sessionStorage和localStorage
- 今天开始写博客,没错。
- RED ROSE