Android TouchEvent事件传递机制初识

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

一. 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

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


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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值