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

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

很简单的三层,下面通过控制上面三个方法的返回,看事件的传递。
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_DOWN05-13 13:04:19.521 32126-32126/focus.teach.toucheventdemo I/focus.teach.toucheventdemo.LinearLayoutOne: LinearLayoutOne---onInterceptTouchEvent---ACTION_DOWN05-13 13:04:19.521 32126-32126/focus.teach.toucheventdemo I/focus.teach.toucheventdemo.LinearLayoutTwo: LinearLayoutTwo---dispatchTouchEvent---ACTION_DOWN05-13 13:04:19.521 32126-32126/focus.teach.toucheventdemo I/focus.teach.toucheventdemo.LinearLayoutTwo: LinearLayoutTwo---onInterceptTouchEvent---ACTION_DOWN05-13 13:04:19.521 32126-32126/focus.teach.toucheventdemo I/focus.teach.toucheventdemo.MyTextView: MyTextView---dispatchTouchEvent---ACTION_DOWN05-13 13:04:19.521 32126-32126/focus.teach.toucheventdemo I/focus.teach.toucheventdemo.MyTextView: MyTextView---onTouchEvent---ACTION_DOWN05-13 13:04:19.522 32126-32126/focus.teach.toucheventdemo I/focus.teach.toucheventdemo.LinearLayoutTwo: LinearLayoutTwo---onTouchEvent---ACTION_DOWN05-13 13:04:19.522 32126-32126/focus.teach.toucheventdemo I/focus.teach.toucheventdemo.LinearLayoutOne: LinearLayoutOne---onTouchEvent---ACTION_DOWN05-13 13:04:19.522 32126-32126/focus.teach.toucheventdemo I/focus.teach.toucheventdemo.MainActivity: MainActivity---onTouchEvent---ACTION_DOWN05-13 13:04:19.532 32126-32126/focus.teach.toucheventdemo I/focus.teach.toucheventdemo.MainActivity: MainActivity---onTouchEvent---ACTION_MOVE05-13 13:04:19.999 32126-32126/focus.teach.toucheventdemo I/focus.teach.toucheventdemo.MainActivity: MainActivity---onTouchEvent---ACTION_MOVE05-13 13:04:20.015 32126-32126/focus.teach.toucheventdemo I/focus.teach.toucheventdemo.MainActivity: MainActivity---onTouchEvent---ACTION_MOVE05-13 13:04:20.048 32126-32126/focus.teach.toucheventdemo I/focus.teach.toucheventdemo.MainActivity: MainActivity---onTouchEvent---ACTION_MOVE05-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_DOWN05-13 13:19:22.413 14442-14442/focus.teach.toucheventdemo I/focus.teach.toucheventdemo.LinearLayoutOne: LinearLayoutOne---onInterceptTouchEvent---ACTION_DOWN05-13 13:19:22.413 14442-14442/focus.teach.toucheventdemo I/focus.teach.toucheventdemo.LinearLayoutTwo: LinearLayoutTwo---dispatchTouchEvent---ACTION_DOWN05-13 13:19:22.413 14442-14442/focus.teach.toucheventdemo I/focus.teach.toucheventdemo.LinearLayoutTwo: LinearLayoutTwo---onInterceptTouchEvent---ACTION_DOWN05-13 13:19:22.414 14442-14442/focus.teach.toucheventdemo I/focus.teach.toucheventdemo.LinearLayoutTwo: LinearLayoutTwo---onTouchEvent---ACTION_DOWN05-13 13:19:22.415 14442-14442/focus.teach.toucheventdemo I/focus.teach.toucheventdemo.LinearLayoutOne: LinearLayoutOne---onTouchEvent---ACTION_DOWN05-13 13:19:22.416 14442-14442/focus.teach.toucheventdemo I/focus.teach.toucheventdemo.MainActivity: MainActivity---onTouchEvent---ACTION_DOWN05-13 13:19:22.434 14442-14442/focus.teach.toucheventdemo I/focus.teach.toucheventdemo.MainActivity: MainActivity---onTouchEvent---ACTION_MOVE05-13 13:19:22.503 14442-14442/focus.teach.toucheventdemo I/focus.teach.toucheventdemo.MainActivity: MainActivity---onTouchEvent---ACTION_MOVE05-13 13:19:22.518 14442-14442/focus.teach.toucheventdemo I/focus.teach.toucheventdemo.MainActivity: MainActivity---onTouchEvent---ACTION_MOVE05-13 13:19:22.552 14442-14442/focus.teach.toucheventdemo I/focus.teach.toucheventdemo.MainActivity: MainActivity---onTouchEvent---ACTION_MOVE05-13 13:19:22.567 14442-14442/focus.teach.toucheventdemo I/focus.teach.toucheventdemo.MainActivity: MainActivity---onTouchEvent---ACTION_MOVE05-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.逻辑抽象
拿上面第二个示例,画出对应的逻辑图,如下所示:
[外链图片转存失败(img-nMtC9Vxp-1569079045194)(https://img-blog.csdn.net/20160513140734515)]

demo下载地址:
http://download.csdn.net/detail/dfskhgalshgkajghljgh/9525803

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


欢迎一起交流讨论
群号:469890293


关注我的公众号,更多优质文章将通过公众号推送。
微信扫一扫下方二维码即可关注:
Android TouchEvent事件传递机制初识_第1张图片

更多相关文章

  1. Android利用已有控件实现自定义控件
  2. [Android] AutoCompleteTextView:自动完成输入内容的控件
  3. android导入xxx.aar依赖方法
  4. Android ListView滑动后背景变黑问题解决方法
  5. Android Canvas绘图描述Android Canvas 方法总结

随机推荐

  1. Android(安卓)Base64字符串转换成图片
  2. android文件关联之mime type
  3. Toast.LENGTH_LONG和Toast.LENGTH_SHORT
  4. android按钮按下的效果
  5. Android学习笔记_72_Spinner的用法
  6. android imageView 自适应大小
  7. Android应用程序组件Content Provider的
  8. Android控件笔记——在界面中显示图片
  9. Android中创建与几种解析xml的方法!
  10. EditText实时判断输入字符数