IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 移动开发 -> Android事件分发之源码分析,作为Android开发程序员 -> 正文阅读

[移动开发]Android事件分发之源码分析,作为Android开发程序员

Activity

Activity中主要两个与事件传递相关的方法,dispatchTouchEvent() 和 onTouchEvent(),事件传递由 Activity 的 dispatchTouchEvent() 方法开始。

事件分发

Activity中的事件分发方法:dispatchTounchEvent(),其源码如下:




//事件分发

public boolean dispatchTouchEvent(MotionEvent ev) {

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

        //空方法

        onUserInteraction();

    }

    if (getWindow().superDispatchTouchEvent(ev)) {

        return true;

    }

    //onTouchEvent()方法默认返回false

    return onTouchEvent(ev);

}



上面代码中显然只处理了 ACTION_DOWN 事件, 说明 ACTION_DOWN 事件才会触发事件的分发,接着调用了 Window 类的 superDispatchTouchEvent(ev)方法,这是一个抽象方法,那么当调用这个方法的时候,就会去调用具体子类中的方法,Window 类的具体子类就是 PhoneWindow 类,里面的具体实现的 superDispatchTouchEvent(ev) 方法如下:


//Window类里面的抽象方法

public abstract boolean superDispatchTouchEvent(MotionEvent event);

//Window子类PhoneWindow类中superDispatchTouchEvent()方法的具体实现

@Override  

public boolean superDispatchTouchEvent(MotionEvent event) {  

    return mDecor.superDispatchTouchEvent(event);  

}



显然,这里有调用了mDecor.superDispatchTouchEvent(event),mDecor 是一个 PhoneWindow.DecorView 对象,这也是窗口的顶层视图。它是一个真正 Activity 的 root view,它继承了 FrameLayout,通过 super.dispatchTouchEvent,会把 touchevent 派发给各个 activity 的子 view,也就是我们在 Activity.onCreat 方法中 setContentView 时设置的 view,代码参考如下:


//DecorView类声明

private final class DecorView extends FrameLayout implements RootViewSurfaceTaker {

    ...

    public boolean superDispatchTouchEvent(MotionEvent event) {

        //这里又调用了FrameLayout中的dispatchTouchEvent方法

        return super.dispatchTouchEvent(event);

    } 

    ...

}



由于在 FrameLayout 并没有重写 dispatchTouchEvent(event) 方法,因此我们需要 FrameLayout 的父类也就是 ViewGroup 中该方法的实现,由该方法进行事件的具体分发,这里具体事件分发过程有待研究。

事件处理

Activity 中的事件处理方法:onTouchEvent(),其源码如下:


//事件处理,默认返回false

public boolean onTouchEvent(MotionEvent event) {

        if (mWindow.shouldCloseOnTouch(this, event)) {

            finish();

            return true;

        }

        //默认返回false

        return false;

    }



由于对于onTouchEvent()方法来说,事件传递是向父控件传递的,即使返回false,事件也相当于被消费了。

注意:Activity进行事件分发时,只有return super.dispatchTouchEvent(ev)时,事件才继续向下传递,返回true或false都事件就被消费了,也就是终止了事件的传播。

ViewGroup

ViewGroup中主要三个与事件传递相关的方法:dispatchTouchEvent()、onInterceptTouchEvent()和onTouchEvent(),具体如下:

事件分发

ViewGroup中的事件分发方法:dispatchTouchEvent(),其源码如下:


@Override

public boolean dispatchTouchEvent(MotionEvent ev) {

    ...

    //dispatchTouchEvent()方法默认返回false

    boolean handled = false;



    //给方法决定是否拦截事件的分发

    onInterceptTouchEvent(ev);

    ...

    //默认情况下canceled和intercepted为false

    if (!canceled && !intercepted) {

        ...

        //该方法将事件传递给子View

        dispatchTransformedTouchEvent(ev, false, child, idBitsToAssign)) {

        ...        

    }



    return handled;

}



这个方法的作用就是遍历ViewGroup中的子View,将事件(ACTION_DOWN)交有子View进行处理,里面主要调用了onInterceptTouchEvent()和dispatchTransformedTouchEvent()方法,onInterceptTouchEvent()默认返回 false,下面是 dispatchTransformedTouchEvent() 方法的主要源码如下:


private boolean dispatchTransformedTouchEvent(MotionEvent event, boolean cancel,

            View child, int desiredPointerIdBits){

    ...



    if (child == null) {

        handled = super.dispatchTouchEvent(event);

    } else {

        //进行子 View 的事件分发

        handled = child.dispatchTouchEvent(event);

    }    

    ...

    return handled;

}



显然,dispatchTransformedTouchEvent() 方法主要进行子 View 的事件分发,如果没有子 View,则调用父 View 的 dispatchTouchEvent(event) 方法。

事件拦截

ViewGroup 中的事件分发方法 onInterceptTouchEvent() ,其源码如下:


public boolean onInterceptTouchEvent(MotionEvent ev) {

    ...

    //默认返回false

    return false;

}



该方法默认返回 false,表示不拦截向子 View 的事件分发,该方法在 ViewGroup 的 dispatchTouchEvent() 方法中被调用。

事件处理

ViewGroup 中没有自己的 onTouchEvent() 事件处理方法 ,ViewGroup 继承 View,其事件处理方法就是 View 的事件处理方法,其方法如下:


public boolean onTouchEvent(MotionEvent event) {

    ...

    //默认返回 false

    return false;

}



该方法进行相关事件的处理,如果返回 true ,表示事件被处理,具体使用情况将在在下文中记录。

View

View 中主要两个与事件分发相关的方法:dispatchTouchEvent() 和 onTouchEvent() 方法,具体如下:

  移动开发 最新文章
Vue3装载axios和element-ui
android adb cmd
【xcode】Xcode常用快捷键与技巧
Android开发中的线程池使用
Java 和 Android 的 Base64
Android 测试文字编码格式
微信小程序支付
安卓权限记录
知乎之自动养号
【Android Jetpack】DataStore
上一篇文章      下一篇文章      查看所有文章
加:2021-09-06 11:16:17  更:2021-09-06 11:18:17 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/23 17:01:30-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码