Android 事件分发机制
2016-07-28 18:07
447 查看
http://blog.csdn.net/mackkill/article/details/50923717
标签: android经验
2016-03-18 15:51 490人阅读 评论(0) 收藏 举报
分类:
学习经验(12)
版权声明:本文为博主原创文章,未经博主允许不得转载。
在写自定义控件或者view的时候肯定会涉及到事件的分发,今天来记录下自己的学习经验。
首先我们要知道跟touch事件有关的方法有:
dispatchTouchEvent()
用来分派事件。其中调用了onInterceptTouchEvent()和onTouchEvent(),一般不重写该方法。
onInterceptTouchEvent()
用来拦截事件。默认是:{return false;}表示不拦截该事件,事件将向下传递。若重写该方法,使其返回true,则表示拦截事件终止向下传递
onTouchEvent()
用来处理事件。返回true则表示该View能处理该事件,事件将被消费掉;返回false表示不能处理,则把事件继续向下分发,如果向下没有子view则向上返回上一级处理,以此类推继续返。
这里还有个
1、
2、
可以看到一个是在重写控件的时候重写的方法,一个是在Activity里面设置监听时调用的方法。
但是onTouchListener的onTouch方法优先级比onTouchEvent高,如果都设置的话onTouch会先触发。
假如onTouch方法返回false会接着触发onTouchEvent,反之如果返回true则onTouchEvent方法不会被调用。
诸如onclick事件的实现等等都基于onTouchEvent,假如onTouch返回true,这些事件将不会被触发。
他俩都可以监听手势操作。由于平时我们一般都会比较偏向重写onTouchEvent方法。所以这里就只拿onTouchEvent来说。
好了言归正传接着说上述三个方法,上述三个方法不同的类拥有的方法也不同:
1、Activity类拥有:
2、ViewGroup(继承自View,表示可以有子控件,如FrameLayout、Linearlayout、Listview这些): 三个方法都拥有。
3、View(普通的控件,没有子布局的,如Button、TextView):
现在用一个例子来具体说下过程:
A –> frameLayout
C –> LinearLayout
D –> TextView
现在开始点击D
图是自带的画图工具画的,希望大家凑合看下。。。
总得来说,当点击事件到底层View(一般是个ViewGroup)以后,就会调用这个ViewGroup的dispatchTouchEvent方法,如果这个ViewGroup拦截事件返回true(默认是返回false),则事件由此ViewGroup处理,如果此时ViewGroup的OnTouchListener被设置,则onTouch会被调用,否则onTouchEvent会被调用,如果都提供的话就是上面所说的onTouch优先级高会屏蔽掉onTouchEvent。反之如果ViewGroup的拦截事件返回false,则事件会传递给在他点击链上的子View,这个时候子View的dispatchTouchEvent被调用,到此为止事件就从底层View传递到它的上一层View了,接下来的和其底层View传过来的行为一致了,如此循环直到整个事件派发结束。如果一个点击事件的子View的onTouchEvent返回了false,其父的onTouchEvent也返回了false,所有的View都没去处理,则最终会由Activity来处理。
如果你看过我自定义view-SlideSwitch开源详解的就会发现
Android 事件分发机制
标签: android经验2016-03-18 15:51 490人阅读 评论(0) 收藏 举报
分类:
学习经验(12)
版权声明:本文为博主原创文章,未经博主允许不得转载。
在写自定义控件或者view的时候肯定会涉及到事件的分发,今天来记录下自己的学习经验。
首先我们要知道跟touch事件有关的方法有:
<code class="hljs java has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: "Source Code Pro", monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">boolean</span> <span class="hljs-title" style="box-sizing: border-box;">dispatchTouchEvent</span>(MotionEvent ev); <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">boolean</span> <span class="hljs-title" style="box-sizing: border-box;">onInterceptTouchEvent</span>(MotionEvent ev); <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">boolean</span> <span class="hljs-title" style="box-sizing: border-box;">onTouchEvent</span>(MotionEvent ev); </code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li></ul>
dispatchTouchEvent()
用来分派事件。其中调用了onInterceptTouchEvent()和onTouchEvent(),一般不重写该方法。
onInterceptTouchEvent()
用来拦截事件。默认是:{return false;}表示不拦截该事件,事件将向下传递。若重写该方法,使其返回true,则表示拦截事件终止向下传递
onTouchEvent()
用来处理事件。返回true则表示该View能处理该事件,事件将被消费掉;返回false表示不能处理,则把事件继续向下分发,如果向下没有子view则向上返回上一级处理,以此类推继续返。
这里还有个
public boolean onTouch(View v, MotionEvent event)方法要说明下:
onTouchEvent(MotionEvent ev)和
onTouch(View v, MotionEvent event)都可以用来处理手势监听,他们的区别我们通过两个例子来了解:
1、
<code class="hljs java has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: "Source Code Pro", monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-class" style="box-sizing: border-box;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">class</span> <span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">MyButton</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">extends</span> <span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">Button</span> {</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-title" style="box-sizing: border-box;">MyButton</span>(Context context) { <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">super</span>(context); <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// TODO Auto-generated constructor stub </span> } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-title" style="box-sizing: border-box;">MyButton</span>(Context context, AttributeSet attributeSet) { <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">super</span>(context, attributeSet); <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// TODO Auto-generated constructor stub </span> } <span class="hljs-annotation" style="color: rgb(155, 133, 157); box-sizing: border-box;">@Override</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">boolean</span> <span class="hljs-title" style="box-sizing: border-box;">onTouchEvent</span>(MotionEvent event) { <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">super</span>.onTouchEvent(event); ; } </code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li></ul>
2、
<code class="hljs java has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: "Source Code Pro", monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">MyButton= (Button) findViewById(R.id.mybutton); MyButton.setOnTouchListener(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> OnTouchListener() { <span class="hljs-annotation" style="color: rgb(155, 133, 157); box-sizing: border-box;">@Override</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">boolean</span> <span class="hljs-title" style="box-sizing: border-box;">onTouch</span>(View v, MotionEvent event) { <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// TODO Auto-generated method stub</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">false</span>; } });</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li></ul>
可以看到一个是在重写控件的时候重写的方法,一个是在Activity里面设置监听时调用的方法。
但是onTouchListener的onTouch方法优先级比onTouchEvent高,如果都设置的话onTouch会先触发。
假如onTouch方法返回false会接着触发onTouchEvent,反之如果返回true则onTouchEvent方法不会被调用。
诸如onclick事件的实现等等都基于onTouchEvent,假如onTouch返回true,这些事件将不会被触发。
他俩都可以监听手势操作。由于平时我们一般都会比较偏向重写onTouchEvent方法。所以这里就只拿onTouchEvent来说。
好了言归正传接着说上述三个方法,上述三个方法不同的类拥有的方法也不同:
1、Activity类拥有:
dispatchTouchEvent(); onTouchEvent();
2、ViewGroup(继承自View,表示可以有子控件,如FrameLayout、Linearlayout、Listview这些): 三个方法都拥有。
3、View(普通的控件,没有子布局的,如Button、TextView):
dispatchTouchEvent(); onTouchEvent();
现在用一个例子来具体说下过程:
A –> frameLayout
C –> LinearLayout
D –> TextView
现在开始点击D
图是自带的画图工具画的,希望大家凑合看下。。。
总得来说,当点击事件到底层View(一般是个ViewGroup)以后,就会调用这个ViewGroup的dispatchTouchEvent方法,如果这个ViewGroup拦截事件返回true(默认是返回false),则事件由此ViewGroup处理,如果此时ViewGroup的OnTouchListener被设置,则onTouch会被调用,否则onTouchEvent会被调用,如果都提供的话就是上面所说的onTouch优先级高会屏蔽掉onTouchEvent。反之如果ViewGroup的拦截事件返回false,则事件会传递给在他点击链上的子View,这个时候子View的dispatchTouchEvent被调用,到此为止事件就从底层View传递到它的上一层View了,接下来的和其底层View传过来的行为一致了,如此循环直到整个事件派发结束。如果一个点击事件的子View的onTouchEvent返回了false,其父的onTouchEvent也返回了false,所有的View都没去处理,则最终会由Activity来处理。
如果你看过我自定义view-SlideSwitch开源详解的就会发现
public boolean onTouchEvent(MotionEvent event)方法里面的第一句话
getParent().requestDisallowInterceptTouchEvent(true);这句话出现的原因是当SlideSwitch放在ScrollView里面滑动的时候会和ScrollView的滑动产生冲突,所以这里我们需要在按住SlideSwitch滑动的时候屏蔽掉ScrollView的滑动。通过requestDisallowInterceptTouchEvent()我们可以对disallowIntercept的值进行修改。这里为什么这么修改,大家有兴趣可以查看下源码,这里就不给提供了。
相关文章推荐
- Android DiskLruCache完全解析,硬盘缓存的最佳方案
- android MediaRecorder录制音视频实现直播的基础
- 初识Android Studio目录
- 【Android进阶】实现各种各样的Tab切换效果
- ffmpeg支持x264的android平台编译
- android插件化学习笔记(二)
- Android Studio开发环境建立aidl文件,生成相应的java文件
- Android数据库两种操作方式介绍: SQLite与ORMLite
- ANDROID 监听返回键,重写事件
- Android系统的版本号与API的对应表
- Android 仿今日头条首页标题栏效果
- Android 获取设备网卡信息
- Android AndFix 热修复框架
- Android调用WEBSERVER发送信息到服务器
- Android 读取CPU信息方法
- Android ORMLite 框架的入门用法
- android获取内存信息方法
- Android 快速开发系列 ORMLite 框架最佳实践 标签: AndroidORMLite 2014-09-07 23:47 62916人阅读 评论(36) 收藏 举报 分类: 【Androi
- android中 IntDef注解的使用
- 六、封装EventBus