Android 点击事件图示源码解析

阅读: 评论:0

Android 点击事件图示源码解析

Android 点击事件图示源码解析

前言

仅用于知识点简介,详细描述建议百度,主要是一些个人的理解总结,可以在面试时来回答,所以并不是很详细,只是总结~

Android 点击事件

1. 传递过程

  1. 分发流程:Activity -> Window -> DecorView -> ViewGroup… -> View
  2. 消费流程:View -> ViewGroup… -> DecorView -> Window -> Activity

2. 图示

3. 源码解释

3.1 代码1 - Activity.dispatchTouchEvent
public boolean dispatchTouchEvent(MotionEvent ev) {if (ev.getAction() == MotionEvent.ACTION_DOWN) {// 点击事件会在 onUserInteraction 通知onUserInteraction();}// 向 Window 分发if (getWindow().superDispatchTouchEvent(ev)) {// 如果消耗 则 返回 truereturn true;}// Window 下均未消耗,则自己处理 onTouchEvent()return onTouchEvent(ev);
}
3.2 代码2 - ViewGroup.dispatchTouchEvent
public boolean dispatchTouchEvent(MotionEvent ev) {...// 检查是否拦截final boolean intercepted;if (actionMasked == MotionEvent.ACTION_DOWN|| mFirstTouchTarget != null) {// 是否禁止拦截final boolean disallowIntercept = (mGroupFlags & FLAG_DISALLOW_INTERCEPT) != 0;if (!disallowIntercept) {// 未禁止拦截,调用 onInterceptTouchEvent 检查是否拦截intercepted = onInterceptTouchEvent(ev);// 重新载入 action,所以在 onInterceptTouchEvent 中 ev 的 action 的变更是不会生效的ev.setAction(action); } else {intercepted = false;}} else {// 如果没有触摸目标 touchTarget 且 不是 Down 事件,那么说明从 Down 事件就与本视图无关,不关注后续事件,所以直接屏蔽// 这也是为什么如果拦截了 Down 事件,那么后续的事件都收不到intercepted = true;}...if (!canceled && !intercepted) {...TouchTarget newTouchTarget = null;boolean alreadyDispatchedToNewTouchTarget = false;for (int i = childrenCount - 1; i >= 0; i--) {if (dispatchTransformedTouchEvent(ev, false, child, idBitsToAssign)) {// 检查点击范围内的 childmLastTouchDownTime = ev.getDownTime();if (preorderedList != null) {// childIndex points into presorted list, find original indexfor (int j = 0; j < childrenCount; j++) {if (children[childIndex] == mChildren[j]) {mLastTouchDownIndex = j;break;}}} else {mLastTouchDownIndex = childIndex;}mLastTouchDownX = ev.getX();mLastTouchDownY = ev.getY();// 添加到     mFirstTouchTargetnewTouchTarget = addTouchTarget(child, idBitsToAssign);alreadyDispatchedToNewTouchTarget = true;break;}}}...if (mFirstTouchTarget == null) {// 没有找到点击目标,自己处理点击事件handled = dispatchTransformedTouchEvent(ev, canceled, null,TouchTarget.ALL_POINTER_IDS);} else {// 根据 mFirstTouchTarget 逐级发放点击事件,根据需要向其中的 target 发放 cancel 事件TouchTarget predecessor = null;TouchTarget target = mFirstTouchTarget;while (target != null) {final TouchTarget next = ;if (alreadyDispatchedToNewTouchTarget && target == newTouchTarget) {handled = true;} else {final boolean cancelChild = resetCancelNextUpFlag(target.child)|| intercepted;// 发放事件if (dispatchTransformedTouchEvent(ev, cancelChild,target.child, target.pointerIdBits)) {handled = true;}if (cancelChild) {if (predecessor == null) {mFirstTouchTarget = next;} else { = next;}le();target = next;continue;}}predecessor = target;target = next;}}...return true;
}
3.3 代码3 - View.dispatchTouchEvent
public boolean dispatchTouchEvent(MotionEvent event) {boolean result = false;...if ((mViewFlags & ENABLED_MASK) == ENABLED && handleScrollBarDragging(event)) {// 处理滚动result = true;}ListenerInfo li = mListenerInfo;if (li != null && li.mOnTouchListener != null&& (mViewFlags & ENABLED_MASK) == ENABLED&& Touch(this, event)) {// 有 mOnTouchListener,且Touch 返回 true 消耗了事件result = true;}if (!result && onTouchEvent(event)) {// 如果之前的操作没有消耗事件,则会调用自己的 onTouchEvent 处理事件result = true;}...return result;
}

本文发布于:2024-01-31 23:36:50,感谢您对本站的认可!

本文链接:https://www.4u4v.net/it/170671540832215.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:图示   源码   事件   Android
留言与评论(共有 0 条评论)
   
验证码:

Copyright ©2019-2022 Comsenz Inc.Powered by ©

网站地图1 网站地图2 网站地图3 网站地图4 网站地图5 网站地图6 网站地图7 网站地图8 网站地图9 网站地图10 网站地图11 网站地图12 网站地图13 网站地图14 网站地图15 网站地图16 网站地图17 网站地图18 网站地图19 网站地图20 网站地图21 网站地图22/a> 网站地图23