美文网首页
Android事件分发

Android事件分发

作者: 海内灬存知己 | 来源:发表于2020-01-07 20:48 被阅读0次

努力第一弹,把事件分发弄明白,本文主要看考资料有

Android事件分发机制详解:史上最全面、最易懂
android中的事件传递和处理机制

一问:为什么要研究事件分发,事件分发对我们有什么帮助?

原因有二:

第一点:面试,做开发,难免会换工作,当面试官问你的时候,你如果支支吾吾答不上来,想必对你的印象会大打折扣

第二点:开发中的应用,例如一些滑动嵌套,掌握了事件分发,分分钟解决问题

既然我们已经知道了事件分发是非常有意义的知识点,那么下一步就是学习它

二问:事件分发的对象是谁?

答:点击事件(Touch事件

定义:

当用户触摸屏幕时(View或ViewGroup派生的控件),将产生点击事件(Touch事件)

Touch事件的相关细节(发生触摸的位置、时间等)被封装成MotionEvent对象

事件类型(4种)

事件类型具体动作

MotionEvent.ACTION_DOWN按下View(所有事件的开始)

MotionEvent.ACTION_UP抬起View(与DOWN对应)

MotionEvent.ACTION_MOVE滑动View

MotionEvent.ACTION_CANCEL结束事件(非人为原因)

三问:事件分发的本质

答:将点击事件(MotionEvent)传递到某个具体的View& 处理的整个过程

即 事件传递的过程 = 分发过程。

四问:事件在哪些对象之间进行传递?

答:Activity、ViewGroup、View

五问:事件分发过程由哪些方法协作完成?

答:dispatchTouchEvent() 、onInterceptTouchEvent()和onTouchEvent()

经过以上五问以后,我们大概应该对事件分发有个大体的了解了,下面我们就去看一下,事件分发是如何分发的

一:Activity的事件分发机制

当一个点击事件发生时,事件最先传到Activity的dispatchTouchEvent()进行事件分发

源码分析:


public boolean dispatchTouchEvent(MotionEvent ev) {

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

//这个方法是按下的时候执行,所以一定会执行,一个空方法而已

当此activity在栈顶时,触屏点击按home,back,menu键等都会触发此方法,可以忽略

onUserInteraction();

    }

//这句话实现了从Activity向ViewGroup传递了,(分析一)

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

return true;

    }

return onTouchEvent(ev);

}

分析一:

为什么说这句话实现了从Activity向ViewGroup传递了呢?

因为window的实现类是PhoneWindow,而PhoneWindow的superDispatchTouchEvent方法返回 mDecor.superDispatchTouchEvent(event);

b. DecorView继承自FrameLayout,是所有界面的父类

c. FrameLayout是ViewGroup的子类,故DecorView的间接父类 = ViewGroup

image

那么,ViewGroup的dispatchTouchEvent()什么时候返回true/false?请继续往下看ViewGroup事件的分发机制

二:ViewGroup事件的分发机制

从上面Activity事件分发机制可知,ViewGroup事件分发机制从dispatchTouchEvent()开始

源码分析:


//仅贴出关键代码,省略无用部分

@Override

public boolean dispatchTouchEvent(MotionEvent ev) {

// 分析一

if (!canceled && !**intercepted**) {

// 通过for循环,遍历了当前ViewGroup下的所有子View

for (int i = childrenCount -1; i >=0; i--) {

//分析二

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

......

break;

}}}}

分析一:

intercepted 是onInterceptTouchEvent()的返回值

a. 若在onInterceptTouchEvent()中返回false(即不拦截事件),就会让第二个值为true,从而进入到条件判断的内部

b. 若在onInterceptTouchEvent()中返回true(即拦截事件),就会让第二个值为false,从而跳出了这个条件判断

分析二:dispatchTransformedTouchEvent(ev, false, child, idBitsToAssign)方法内部调用了child.dispatchTouchEvent(event);

从而实现了事件从ViewGroup到View的传递

image

三:View事件的分发机制

源码分析:


public boolean dispatchTouchEvent(MotionEvent event) {

分析一

if (li !=null && li.mOnTouchListener !=null

        && (mViewFlags &ENABLED_MASK) ==ENABLED

        && li.mOnTouchListener.onTouch(this, event)) {

result =true;

}

分析二

if (!result && onTouchEvent(event)) {

result =true;

}

return result;

}

分析一:

满足这三个条件就返回true,否则向下进行,其中最后一个条件是由mOnTouchListener提供者返回值,例如:


button.setOnTouchListener(new OnTouchListener(){

@Override

public boolean onTouch (View v , Motion Eventevent){

return false;

}});

分析二:

调用onTouchEvent(event),结果为true则返回true,onTouchEvent方法中会执行OnClick()方法

image

相关文章

网友评论

      本文标题:Android事件分发

      本文链接:https://www.haomeiwen.com/subject/dxmdactx.html