博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
几行代码看懂android View的事件传递机制(视图逻辑)
阅读量:4291 次
发布时间:2019-05-27

本文共 2464 字,大约阅读时间需要 8 分钟。

/** * View的事件分发 */public class View{	public boolean dispatchTouchEvent(MotionEvent ev){		boolean result = false;		// 先判断是否设置了onTouchListener,如果设置了,就调用		if (mOnTouchListener != null && mOnTouchListener.onTouch(ev)) {			result = true;		}		// 如果没有设置onTouchListener,或者调用了onTouch后返回了false,那么就调用onTouchEvent		if (!result && onTouchEvent(ev)) {			result = true;		}		return result;	}	public boolean onTouchEvent(MotionEvent ev){		// 如果View可点击		if (isClickable()) {			switch (ev.getAction()) {				...				case MotionEvent.ACTION_UP:					...					// 判断是否设置了onClickListener,设置了就调用,并消耗事件					if (mOnClickListener != null) {						mOnClickListener.onClick(this);					}					...					break;				...			}			// 可点击的View,默认会消耗掉事件			return true;		}		// 不可点击的View,默认不消耗事件		return false;	}}

/** * ViewGroup的事件分发 */public class ViewGroup extends View{	// 一旦有子元素消耗了事件,这个子元素就被赋值给mFirstTouchTarget	public View mFirstTouchTarget = null;	public boolean dispatchTouchEvent(MotionEvent ev){		int action = ev.getAction();		boolean handled = false;		boolean intercepted;		// DOWN事件,或者有子元素消耗事件,则进入if语句内,判断是否拦截		if (action == MotionEvent.ACTION_DOWN || mFirstTouchTarget != null) {			// 取出 是否允许拦截 的标记,默认是false。子元素可以通过requestDisallowInterceptTouchEvent(true);将这个标记设置为true			boolean disallow = getFlagDisallowIntercept();			if (!disallow) {				// 允许拦截,调用onInterceptTouchEvent判断是否拦截				intercepted = onInterceptTouchEvent(ev);			}else {				// 不允许拦截,直接不拦截				intercepted = false;			}		}else {			// 非DOWN事件,或者没有子元素消耗了事件,直接拦截			intercepted = true;		}		// 如果有子元素消耗事件,alreadyDispatched就被赋值为true		boolean alreadyDispatched = false;		if (!intercepted) {			// 不拦截事件			// 遍历子元素			for (int i = 0 ; i < mChildList().size() ; i++) {				View child = mChildList.get(i);				float x = ev.getX();				float y = ev.getY();				if (x >= child.left && x <= child.right && y >= child.top && y <= child.bottom) {					// 事件位于子元素所在区域内,将事件分发给子元素					if (child.dispatchTouchEvent(ev)) {						// 子元素消耗了事件						mFirstTouchTarget = child;						alreadyDispatched = true;						// 跳出循环,不再分发						break;					}				}							}		}		if (mFirstTouchTarget == null) {			// 没有子元素消耗事件			// ViewGroup自行处理事件			super.dispatchTouchEvent(ev);					}else {			// 有子元素消耗了事件,则后续事件全部交给该子元素处理,不管他是否消耗事件			if (alreadyDispatched) {				mFirstTouchTarget.dispatchTouchEvent(ev);				handled = true;			}		}		return handled;	}	public boolean onTouchEvent(MotionEvent ev){		super.onTouchEvent(ev);	}	public boolean onInterceptTouchEvent(MotionEvent ev){		return false;	}}

转载地址:http://rdegi.baihongyu.com/

你可能感兴趣的文章
Java开发大型互联网企业微服务架构简介及罕见的问题点
查看>>
初探Java源码之ArrayList
查看>>
Mysql性能优化实战:数据库锁的介绍与索引查找原理
查看>>
Java程序员该如何提升让自己成为高薪架构师?
查看>>
「mysql优化专题」这大概是一篇最好的mysql优化入门文章(1)
查看>>
Java虚拟机体系结构由几部分组成?
查看>>
用分布式日志优化单机数据库系统将成未来标配?
查看>>
Java互联网架构-深入理解MQ实现分布式事务
查看>>
Spring boot整合Springfox在线生成restful的api doc
查看>>
简单MySQL教程二
查看>>
mysql学习之 explain
查看>>
java搜索引擎Apache的solr初探-安装使用导入mysql数据
查看>>
Java互联网架构-企业级实战秒杀系统优化方案与应用思路
查看>>
简单介绍一下Spring / java中Spring框架7大核心模块的作用,如何在面试中侃侃而谈?/ Spring体系常用项目一览
查看>>
为什么使用mq?
查看>>
配置使用IM表达式的基本任务
查看>>
自定义JSP标签自动完成对页面按钮做权限拦截处理
查看>>
Java互联网架构-负载均衡原理与实现方案
查看>>
实用SQL函数集合(五)《格式化函数》
查看>>
jvm-运行时内存结构
查看>>