Android事件传递机制(三)deprecated
发布日期:2021-06-30 11:23:10
浏览次数:2
分类:技术文章
本文共 13001 字,大约阅读时间需要 43 分钟。
main.xml如下:
MainActivity如下:
package cn.c;import android.os.Bundle;import android.app.Activity;import android.view.MotionEvent;//Demo描述://分析Android事件分发和处理机制//总结://1 ViewGroup继承自View// 事件的传递方向为:从最外层(Activity)传递至最内层(某个View)// 事件的消费方向为:从最内层(某个View)传递至最外层(Activity)// 该两个方向是相反的//2 ViewGroup中事件处理的流程是:// dispatchTouchEvent->onInterceptTouchEvent->onTouchEvent// View中事件处理的流程是:// dispatchTouchEvent->onTouchEvent//3 ViewGroup中onInterceptTouchEvent默认值是false// 表示未拦截// ViewGroup中onTouchEvent默认值是false// 表示未消费// View中onTouchEvent返回默认值是true// 表示已消费//测试方法://在Android事件传递机制(二)的基础上继续验证和实践中提到的原理//测试步骤://将MyFrameLayout的dispatchTouchEvent返回false即不分发//测试结果://05-13 10:42:32.749: I/System.out(19671): ===> MainActivity 中调用 onCreate()//05-13 10:42:32.749: I/System.out(19671): --------------------------------------------------//05-13 10:42:35.178: I/System.out(19671): ===> MainActivity 中调用 dispatchTouchEvent()//05-13 10:42:35.178: I/System.out(19671): ===> super.dispatchTouchEvent()默认返回true//05-13 10:42:35.178: I/System.out(19671): --------------------------------------------------//05-13 10:42:35.178: I/System.out(19671): ===> MainActivity 中调用 onUserInteraction()//05-13 10:42:35.178: I/System.out(19671): --------------------------------------------------//05-13 10:42:35.178: I/System.out(19671): 外层MyFrameLayout 中调用 dispatchTouchEvent()//05-13 10:42:35.178: I/System.out(19671): super.dispatchTouchEvent()默认返回true 表示继续分发//05-13 10:42:35.178: I/System.out(19671): --------------------------------------------------//05-13 10:42:35.178: I/System.out(19671): ===> MainActivity 中调用 onTouchEvent()--->ACTION_DOWN//05-13 10:42:35.178: I/System.out(19671): super.onTouchEvent()默认返回false 表示未消费事件//05-13 10:42:35.178: I/System.out(19671): --------------------------------------------------//05-13 10:42:35.225: I/System.out(19671): ===> MainActivity 中调用 dispatchTouchEvent()//05-13 10:42:35.225: I/System.out(19671): ===> super.dispatchTouchEvent()默认返回true//05-13 10:42:35.225: I/System.out(19671): --------------------------------------------------//05-13 10:42:35.225: I/System.out(19671): ===> MainActivity 中调用 onTouchEvent()--->ACTION_UP//05-13 10:42:35.225: I/System.out(19671): super.onTouchEvent()默认返回false 表示未消费事件//05-13 10:42:35.225: I/System.out(19671): --------------------------------------------------//结果分析://在最外层的MyFrameLayout的dispatchTouchEvent中返回false即不分发,此时注意://并没有去执行MyFrameLayout的onInterceptTouchEvent!!!可以理解为:都不分发了//就压根没有意义去看是否还要onInterceptTouchEvent拦截了.//所以在资料3中的图是有一些欠缺的.没有注意到该问题//在这个测试中每层里没有一个onTouchEvent()返回true.//所以在后续事件分发的时的情况及原理同下面的测试一样//测试步骤://将MyLinearLayout的onInterceptTouchEvent()返回值设置为true//表示拦截.按照资料2的图四,此时事件的分发dispatchTouchEvent会结束//不会继续往下传递,所以开始执行MyLinearLayout的onTouchEvent()开始执行//且回溯.//测试结果://05-13 10:11:13.108: I/System.out(19000): ===> MainActivity 中调用 onCreate()//05-13 10:11:13.108: I/System.out(19000): --------------------------------------------------//05-13 10:11:15.213: I/System.out(19000): ===> MainActivity 中调用 dispatchTouchEvent()//05-13 10:11:15.213: I/System.out(19000): ===> super.dispatchTouchEvent()默认返回true//05-13 10:11:15.213: I/System.out(19000): --------------------------------------------------//05-13 10:11:15.213: I/System.out(19000): ===> MainActivity 中调用 onUserInteraction()//05-13 10:11:15.213: I/System.out(19000): --------------------------------------------------//05-13 10:11:15.213: I/System.out(19000): 外层MyFrameLayout 中调用 dispatchTouchEvent()//05-13 10:11:15.213: I/System.out(19000): super.dispatchTouchEvent()默认返回true 表示继续分发//05-13 10:11:15.213: I/System.out(19000): --------------------------------------------------//05-13 10:11:15.213: I/System.out(19000): 外层MyFrameLayout 中调用 onInterceptTouchEvent()//05-13 10:11:15.213: I/System.out(19000): super.onInterceptTouchEvent()默认返回false 表示不拦截//05-13 10:11:15.213: I/System.out(19000): --------------------------------------------------//05-13 10:11:15.213: I/System.out(19000): 内层MyLinearLayout 中调用 dispatchTouchEvent()//05-13 10:11:15.213: I/System.out(19000): super.dispatchTouchEvent()默认返回true 表示继续分发//05-13 10:11:15.213: I/System.out(19000): --------------------------------------------------//05-13 10:11:15.213: I/System.out(19000): 内层MyLinearLayout 中调用 onInterceptTouchEvent()//05-13 10:11:15.213: I/System.out(19000): super.onInterceptTouchEvent()默认返回false 表示不拦截//05-13 10:11:15.213: I/System.out(19000): --------------------------------------------------//05-13 10:11:15.225: I/System.out(19000): 内层MyLinearLayout 中调用 onTouchEvent()--->ACTION_DOWN//05-13 10:11:15.225: I/System.out(19000): super.onTouchEvent()默认返回false 表示未消费事件//05-13 10:11:15.225: I/System.out(19000): --------------------------------------------------//05-13 10:11:15.225: I/System.out(19000): 外层MyFrameLayout 中调用 onTouchEvent()--->ACTION_DOWN//05-13 10:11:15.225: I/System.out(19000): super.onTouchEvent()默认返回false 表示未消费事件//05-13 10:11:15.225: I/System.out(19000): --------------------------------------------------//05-13 10:11:15.225: I/System.out(19000): ===> MainActivity 中调用 onTouchEvent()--->ACTION_DOWN//05-13 10:11:15.225: I/System.out(19000): super.onTouchEvent()默认返回false 表示未消费事件//05-13 10:11:15.225: I/System.out(19000): --------------------------------------------------//05-13 10:11:15.241: I/System.out(19000): ===> MainActivity 中调用 dispatchTouchEvent()//05-13 10:11:15.241: I/System.out(19000): ===> super.dispatchTouchEvent()默认返回true//05-13 10:11:15.241: I/System.out(19000): --------------------------------------------------//05-13 10:11:15.241: I/System.out(19000): ===> MainActivity 中调用 onTouchEvent()--->ACTION_UP//05-13 10:11:15.241: I/System.out(19000): super.onTouchEvent()默认返回false 表示未消费事件//05-13 10:11:15.241: I/System.out(19000): --------------------------------------------------//结果分析://结果和我们预计的是一样的.可以看到在MyLinearLayout的onInterceptTouchEvent()中进行了//拦截导致dispatchTouchEvent()的终端,并且MyLinearLayout开始执行onTouchEvent()且回溯.//即MyLinearLayout的onTouchEvent()-->MyFrameLayout的onTouchEvent()-->MainActivity的onTouchEvent()//注意:在处理up事件的时候还是这样的么?不是了!还是那个原因:从最上层(MainActvity)到最下层(MyButton)//每一层的onTouchEvent()返回的均为false.系统会认为该事件没有被消费.所以后续事件分发的时候//不会从MainActivity往下传递dispatchTouchEvent(),直接在MainActivity的onTouchEvent中处理.//重要参考资料://1 http://www.eoeandroid.com/forum.php?mod=viewthread&tid=162460//该资料中第二个图非常重要.//2 http://www.dewen.org/q/2438//该资料中亦有流程图//3 http://blog.csdn.net/ponderforever/article/details/7082787//在该资料的第四段提到://如果事件传递到某一层的子 view的onTouchEvent上了,这个方法返回了 false,//那么这个事件会从这个view往上传递,都是其对应的onTouchEvent来接收.//而如果传递到最上面的onTouchEvent也返回 false的话,这个事件就会"消失",而且接收不到下一次事件.//(我说的一次事件指的是 down 到 up 之间的一系列事件)//针对该段最后一句话:(我说的一次事件指的是 down 到 up 之间的一系列事件)//的补充说明:比如在此Demo的MainActivity的onTouchEvent()中返回false(即默认值)并且//MyButton的onTouchEvent()也返回false(默认的是true)那么外层的MyFrameLayoue//和内层的LinearLayout只能获取到down事件而move和up事件是不能获取的//这点非常的重要.//4 http://blog.csdn.net/ddna/article/details/5473293//5 http://blog.csdn.net/ddna/article/details/5451722//6 http://www.sctarena.com/Article/Article.asp?nid=2802public class MainActivity extends Activity { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); System.out.println("===> MainActivity 中调用 onCreate()"); System.out.println("--------------------------------------------------"); } @Override public boolean dispatchTouchEvent(MotionEvent ev) { System.out.println("===> MainActivity 中调用 dispatchTouchEvent()"); System.out.println("===> super.dispatchTouchEvent()默认返回true"); System.out.println("--------------------------------------------------"); return super.dispatchTouchEvent(ev); } @Override public void onUserInteraction() { System.out.println("===> MainActivity 中调用 onUserInteraction()"); System.out.println("--------------------------------------------------"); super.onUserInteraction(); } @Override public boolean onTouchEvent(MotionEvent event) { switch (event.getAction()) { case MotionEvent.ACTION_DOWN: System.out.println("===> MainActivity 中调用 onTouchEvent()--->ACTION_DOWN"); break; case MotionEvent.ACTION_MOVE: System.out.println("===> MainActivity 中调用 onTouchEvent()--->ACTION_MOVE"); break; case MotionEvent.ACTION_UP: System.out.println("===> MainActivity 中调用 onTouchEvent()--->ACTION_UP"); default: break; } System.out.println("super.onTouchEvent()默认返回false 表示未消费事件"); System.out.println("--------------------------------------------------"); return super.onTouchEvent(event); } }MyFrameLayout如下:
package cn.c;import android.content.Context;import android.util.AttributeSet;import android.view.MotionEvent;import android.widget.FrameLayout;public class MyFrameLayout extends FrameLayout{ public MyFrameLayout(Context context, AttributeSet attrs) { super(context, attrs); } @Override public boolean dispatchTouchEvent(MotionEvent ev) { System.out.println("外层MyFrameLayout 中调用 dispatchTouchEvent()"); System.out.println("super.dispatchTouchEvent()默认返回true 表示继续分发"); System.out.println("--------------------------------------------------"); return super.dispatchTouchEvent(ev); //return false; } //覆写自ViewGroup @Override public boolean onInterceptTouchEvent(MotionEvent ev) { System.out.println("外层MyFrameLayout 中调用 onInterceptTouchEvent()"); System.out.println("super.onInterceptTouchEvent()默认返回false 表示不拦截"); System.out.println("--------------------------------------------------"); return super.onInterceptTouchEvent(ev); //return true; } //注意: //1 ViewGroup是View的子类 //2 ViewGroup中onTouchEvent()方法默认返回的是false @Override public boolean onTouchEvent(MotionEvent event) { switch (event.getAction()) { case MotionEvent.ACTION_DOWN: System.out.println("外层MyFrameLayout 中调用 onTouchEvent()--->ACTION_DOWN"); break; case MotionEvent.ACTION_MOVE: System.out.println("外层MyFrameLayout 中调用 onTouchEvent()--->ACTION_MOVE"); break; case MotionEvent.ACTION_UP: System.out.println("外层MyFrameLayout 中调用 onTouchEvent()--->ACTION_UP"); default: break; } System.out.println("super.onTouchEvent()默认返回false 表示未消费事件"); System.out.println("--------------------------------------------------"); return super.onTouchEvent(event); } }
MyLinearLayout如下:
package cn.c;import android.content.Context;import android.util.AttributeSet;import android.view.MotionEvent;import android.widget.LinearLayout;public class MyLinearLayout extends LinearLayout { public MyLinearLayout(Context context, AttributeSet attrs) { super(context, attrs); } @Override public boolean dispatchTouchEvent(MotionEvent ev) { System.out.println("内层MyLinearLayout 中调用 dispatchTouchEvent()"); System.out.println("super.dispatchTouchEvent()默认返回true 表示继续分发"); System.out.println("--------------------------------------------------"); //return super.dispatchTouchEvent(ev); return false; } //覆写自ViewGroup @Override public boolean onInterceptTouchEvent(MotionEvent ev) { System.out.println("内层MyLinearLayout 中调用 onInterceptTouchEvent()"); System.out.println("super.onInterceptTouchEvent()默认返回false 表示不拦截"); System.out.println("--------------------------------------------------"); return super.onInterceptTouchEvent(ev); } //注意: //1 ViewGroup是View的子类 //2 ViewGroup中onTouchEvent()方法默认返回的是false @Override public boolean onTouchEvent(MotionEvent event) { switch (event.getAction()) { case MotionEvent.ACTION_DOWN: System.out.println("内层MyLinearLayout 中调用 onTouchEvent()--->ACTION_DOWN"); break; case MotionEvent.ACTION_MOVE: System.out.println("内层MyLinearLayout 中调用 onTouchEvent()--->ACTION_MOVE"); break; case MotionEvent.ACTION_UP: System.out.println("内层MyLinearLayout 中调用 onTouchEvent()--->ACTION_UP"); default: break; } System.out.println("super.onTouchEvent()默认返回false 表示未消费事件"); System.out.println("--------------------------------------------------"); return super.onTouchEvent(event); } }
MyButton如下:
package cn.c;import android.content.Context;import android.util.AttributeSet;import android.view.MotionEvent;import android.widget.Button;public class MyButton extends Button{ public MyButton(Context context, AttributeSet attrs) { super(context, attrs); } @Override public boolean dispatchTouchEvent(MotionEvent event) { System.out.println("自定义Button 中调用 dispatchTouchEvent()"); System.out.println("super.dispatchTouchEvent默认返回true"); System.out.println("--------------------------------------------------"); return super.dispatchTouchEvent(event); } //注意: //在View的子类中onTouchEvent()方法默认返回的是true @Override public boolean onTouchEvent(MotionEvent event) { switch (event.getAction()) { case MotionEvent.ACTION_DOWN: System.out.println("自定义Button 中调用 onTouchEvent()--->ACTION_DOWN"); break; case MotionEvent.ACTION_MOVE: System.out.println("自定义Button 中调用 onTouchEvent()--->ACTION_MOVE"); break; case MotionEvent.ACTION_UP: System.out.println("自定义Button 中调用 onTouchEvent()--->ACTION_UP"); break; default: break; } System.out.println("super.onTouchEvent()默认返回true"); System.out.println("--------------------------------------------------"); return super.onTouchEvent(event); } }
转载地址:https://it9527.blog.csdn.net/article/details/8921363 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!
发表评论
最新留言
初次前来,多多关照!
[***.217.46.12]2024年04月21日 10时55分43秒
关于作者
喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!
推荐文章
summernote编辑器数据回显
2019-04-30
summernote禁止图片视频上传
2019-04-30
1.Ribbon注册服务内部调用
2019-04-30
2.Openfeign注册服务内部调用
2019-04-30
1.gateway搭建
2019-04-30
1.Idea或eclipse 运行项目端口被占用处理
2019-04-30
1.JDK1.8新特性值Optional
2019-04-30
1.阿里云上安装jdk8
2019-04-30
2.阿里云上安裝redis
2019-04-30
3.阿里云上安装mysql
2019-04-30
4.阿里云上安装nacos
2019-04-30
6.阿里云上安装kafka
2019-04-30
5.阿里云上安装zookeeper
2019-04-30
7.阿里云上安装RabbitMQ
2019-04-30
JDK8 管道 Stream 详细使用介绍
2019-04-30
2.启停项目脚本
2019-04-30
配置了阿里云安全组端口,浏览器还是不能访问的问题
2019-04-30
mysql出表锁表MySQLTransactionRollbackException: Lock wait timeout exceeded; try restarting transaction
2019-04-30
cron表达式基础配置知识
2019-04-30
lombok基础使用
2019-04-30