最近在复习androidUI的相关知识点,在网上看了一些关于事件分发的文章与视频,因此在此记录一下自己的理解过程。
首先思考2个问题:
什么是事件?什么是事件分发机制?用户与手机的交互会产生一系列的事件 ACTION_DOWN,ACTION_MOVE,ACTION_UP,ACTION_CANCEL。每一个事件都会封装成一个ACTIONEVENT.
事件分发主要解决由谁来处理事件的问题,当你点击Actiivty上的某一个控件时实际点击了不止一个控件,按照下图的显示。 当用户点击了view1时,实际上用户也点击到了ViewGroupA、RootView、DecorView,那事件到底交由哪个控件去处理?另外事件是由一系列的事件序列组成的,从DOWN–>MOVE–>UP,无法割裂开来,要么被忽略,要么都被某一个view所消费。
如果在屏幕点击了一个控件View,最终这个控件View消费了这个事件的话,那大概的分发流程应该是Activity–>ViewGroup–>View。
针对分发流程我们需要关注下面几个方法: dispatchTouchEvent() //分发触摸事件 (dispath 就是分发的意思) onInterceptTouchEvent() // 拦截触摸事件 (Intercept 拦截的意思) onTouchEvent() // 执行触摸事件 (on 可以理解为执行)
无论是Activity,View,ViewGroup都会调用dispatchTouchEvent 与 onTouchEvent。而onInterceptTouchEvent比较特殊,只有在ViewGroup中有。
先看前面一段事件是如何从Activity传递到ViewGroup的。 当我们查看Activity的dispatchTouchEvent()方法,向上追溯可以看到如下的调用路径: Activity–>PhoneWindow–>DecorView–>ViewGroup Activity
public boolean dispatchTouchEvent(MotionEvent ev) { if (ev.getAction() == MotionEvent.ACTION_DOWN) { onUserInteraction(); } if (getWindow().superDispatchTouchEvent(ev)) { return true; } return onTouchEvent(ev); }PhoneWindow
public boolean superDispatchTouchEvent(MotionEvent event) { return mDecor.superDispatchTouchEvent(event); }DecorView
public boolean superDispatchTouchEvent(MotionEvent event) { return super.dispatchTouchEvent(event); }ViewGroup的dispatchTouchEvent()比较长,但总体执行逻辑可以按照下面伪代码表示
public boolean dispatchTouchEvent(MotionEvent ev) { boolean consume = false; if(onInterceptTouchEvent(ev)){ //拦截 将事件交给onTouchEvent()处理 consume = onTouchEvent(ev); }else{ //不拦截 将事件分发给子view consuem = child.dispatchTouchEvent(ev); } return consume; }这里分发的流程就从ViewGrop分发到了View的DispatchTouchEvent.
看下View的DispatchTouchEvent 方法:
public boolean dispatchTouchEvent(MotionEvent event) { //一系列操作.. if (onFilterTouchEventForSecurity(event)) { if ((mViewFlags & ENABLED_MASK) == ENABLED && handleScrollBarDragging(event)) { result = true; } //noinspection SimplifiableIfStatement ListenerInfo li = mListenerInfo; if (li != null && li.mOnTouchListener != null && (mViewFlags & ENABLED_MASK) == ENABLED && li.mOnTouchListener.onTouch(this, event)) { result = true; } if (!result && onTouchEvent(event)) { result = true; } } //又是一系列操作 return result; }上述代码只需要关注2个方法 一个onTouch方法,一个onTouchEvent()方法。了解onTouch方法是在onTouchEvent()之前执行,假如设置了View的mOnTouchListener,那onTouch()方法就会执行。
下面看下View的onTouchEvent()方法,看下它是如何来执行触摸事件的。
public boolean onTouchEvent(MotionEvent event) { //一系列操作1 final boolean clickable = ((viewFlags & CLICKABLE) == CLICKABLE || (viewFlags & LONG_CLICKABLE) == LONG_CLICKABLE) || (viewFlags & CONTEXT_CLICKABLE) == CONTEXT_CLICKABLE; //一系列操作2 if (clickable) { switch (action) { case MotionEvent.ACTION_UP: //一系列操作3 break; case MotionEvent.ACTION_DOWN: //一系列操作4 break; case MotionEvent.ACTION_CANCEL: //一系列操作5 break; case MotionEvent.ACTION_MOVE: //一系列操作6 break; } return true; } return false; }事件最终分发到View(View消费掉事件)
在onTouchEvent方法中,假如view是可以点击或者长按,无论是DOWN,UP ,MOVE,还是CANCEL 方法都会返回true,那就表示这个事件在view中被消费掉。那view的dispatchTouchEvent() 也会返回ture,继续往下追溯,ViewGroup的DispatchTouchEvent()返回true,Activity的dispatchTouchEvent() 返回true。
#mermaid-svg-POnk9RDjolvVgHz0 .label{font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family);fill:#333;color:#333}#mermaid-svg-POnk9RDjolvVgHz0 .label text{fill:#333}#mermaid-svg-POnk9RDjolvVgHz0 .node rect,#mermaid-svg-POnk9RDjolvVgHz0 .node circle,#mermaid-svg-POnk9RDjolvVgHz0 .node ellipse,#mermaid-svg-POnk9RDjolvVgHz0 .node polygon,#mermaid-svg-POnk9RDjolvVgHz0 .node path{fill:#ECECFF;stroke:#9370db;stroke-width:1px}#mermaid-svg-POnk9RDjolvVgHz0 .node .label{text-align:center;fill:#333}#mermaid-svg-POnk9RDjolvVgHz0 .node.clickable{cursor:pointer}#mermaid-svg-POnk9RDjolvVgHz0 .arrowheadPath{fill:#333}#mermaid-svg-POnk9RDjolvVgHz0 .edgePath .path{stroke:#333;stroke-width:1.5px}#mermaid-svg-POnk9RDjolvVgHz0 .flowchart-link{stroke:#333;fill:none}#mermaid-svg-POnk9RDjolvVgHz0 .edgeLabel{background-color:#e8e8e8;text-align:center}#mermaid-svg-POnk9RDjolvVgHz0 .edgeLabel rect{opacity:0.9}#mermaid-svg-POnk9RDjolvVgHz0 .edgeLabel span{color:#333}#mermaid-svg-POnk9RDjolvVgHz0 .cluster rect{fill:#ffffde;stroke:#aa3;stroke-width:1px}#mermaid-svg-POnk9RDjolvVgHz0 .cluster text{fill:#333}#mermaid-svg-POnk9RDjolvVgHz0 div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family);font-size:12px;background:#ffffde;border:1px solid #aa3;border-radius:2px;pointer-events:none;z-index:100}#mermaid-svg-POnk9RDjolvVgHz0 .actor{stroke:#ccf;fill:#ECECFF}#mermaid-svg-POnk9RDjolvVgHz0 text.actor>tspan{fill:#000;stroke:none}#mermaid-svg-POnk9RDjolvVgHz0 .actor-line{stroke:grey}#mermaid-svg-POnk9RDjolvVgHz0 .messageLine0{stroke-width:1.5;stroke-dasharray:none;stroke:#333}#mermaid-svg-POnk9RDjolvVgHz0 .messageLine1{stroke-width:1.5;stroke-dasharray:2, 2;stroke:#333}#mermaid-svg-POnk9RDjolvVgHz0 #arrowhead path{fill:#333;stroke:#333}#mermaid-svg-POnk9RDjolvVgHz0 .sequenceNumber{fill:#fff}#mermaid-svg-POnk9RDjolvVgHz0 #sequencenumber{fill:#333}#mermaid-svg-POnk9RDjolvVgHz0 #crosshead path{fill:#333;stroke:#333}#mermaid-svg-POnk9RDjolvVgHz0 .messageText{fill:#333;stroke:#333}#mermaid-svg-POnk9RDjolvVgHz0 .labelBox{stroke:#ccf;fill:#ECECFF}#mermaid-svg-POnk9RDjolvVgHz0 .labelText,#mermaid-svg-POnk9RDjolvVgHz0 .labelText>tspan{fill:#000;stroke:none}#mermaid-svg-POnk9RDjolvVgHz0 .loopText,#mermaid-svg-POnk9RDjolvVgHz0 .loopText>tspan{fill:#000;stroke:none}#mermaid-svg-POnk9RDjolvVgHz0 .loopLine{stroke-width:2px;stroke-dasharray:2, 2;stroke:#ccf;fill:#ccf}#mermaid-svg-POnk9RDjolvVgHz0 .note{stroke:#aa3;fill:#fff5ad}#mermaid-svg-POnk9RDjolvVgHz0 .noteText,#mermaid-svg-POnk9RDjolvVgHz0 .noteText>tspan{fill:#000;stroke:none}#mermaid-svg-POnk9RDjolvVgHz0 .activation0{fill:#f4f4f4;stroke:#666}#mermaid-svg-POnk9RDjolvVgHz0 .activation1{fill:#f4f4f4;stroke:#666}#mermaid-svg-POnk9RDjolvVgHz0 .activation2{fill:#f4f4f4;stroke:#666}#mermaid-svg-POnk9RDjolvVgHz0 .mermaid-main-font{font-family:"trebuchet ms", verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-POnk9RDjolvVgHz0 .section{stroke:none;opacity:0.2}#mermaid-svg-POnk9RDjolvVgHz0 .section0{fill:rgba(102,102,255,0.49)}#mermaid-svg-POnk9RDjolvVgHz0 .section2{fill:#fff400}#mermaid-svg-POnk9RDjolvVgHz0 .section1,#mermaid-svg-POnk9RDjolvVgHz0 .section3{fill:#fff;opacity:0.2}#mermaid-svg-POnk9RDjolvVgHz0 .sectionTitle0{fill:#333}#mermaid-svg-POnk9RDjolvVgHz0 .sectionTitle1{fill:#333}#mermaid-svg-POnk9RDjolvVgHz0 .sectionTitle2{fill:#333}#mermaid-svg-POnk9RDjolvVgHz0 .sectionTitle3{fill:#333}#mermaid-svg-POnk9RDjolvVgHz0 .sectionTitle{text-anchor:start;font-size:11px;text-height:14px;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-POnk9RDjolvVgHz0 .grid .tick{stroke:#d3d3d3;opacity:0.8;shape-rendering:crispEdges}#mermaid-svg-POnk9RDjolvVgHz0 .grid .tick text{font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-POnk9RDjolvVgHz0 .grid path{stroke-width:0}#mermaid-svg-POnk9RDjolvVgHz0 .today{fill:none;stroke:red;stroke-width:2px}#mermaid-svg-POnk9RDjolvVgHz0 .task{stroke-width:2}#mermaid-svg-POnk9RDjolvVgHz0 .taskText{text-anchor:middle;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-POnk9RDjolvVgHz0 .taskText:not([font-size]){font-size:11px}#mermaid-svg-POnk9RDjolvVgHz0 .taskTextOutsideRight{fill:#000;text-anchor:start;font-size:11px;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-POnk9RDjolvVgHz0 .taskTextOutsideLeft{fill:#000;text-anchor:end;font-size:11px}#mermaid-svg-POnk9RDjolvVgHz0 .task.clickable{cursor:pointer}#mermaid-svg-POnk9RDjolvVgHz0 .taskText.clickable{cursor:pointer;fill:#003163 !important;font-weight:bold}#mermaid-svg-POnk9RDjolvVgHz0 .taskTextOutsideLeft.clickable{cursor:pointer;fill:#003163 !important;font-weight:bold}#mermaid-svg-POnk9RDjolvVgHz0 .taskTextOutsideRight.clickable{cursor:pointer;fill:#003163 !important;font-weight:bold}#mermaid-svg-POnk9RDjolvVgHz0 .taskText0,#mermaid-svg-POnk9RDjolvVgHz0 .taskText1,#mermaid-svg-POnk9RDjolvVgHz0 .taskText2,#mermaid-svg-POnk9RDjolvVgHz0 .taskText3{fill:#fff}#mermaid-svg-POnk9RDjolvVgHz0 .task0,#mermaid-svg-POnk9RDjolvVgHz0 .task1,#mermaid-svg-POnk9RDjolvVgHz0 .task2,#mermaid-svg-POnk9RDjolvVgHz0 .task3{fill:#8a90dd;stroke:#534fbc}#mermaid-svg-POnk9RDjolvVgHz0 .taskTextOutside0,#mermaid-svg-POnk9RDjolvVgHz0 .taskTextOutside2{fill:#000}#mermaid-svg-POnk9RDjolvVgHz0 .taskTextOutside1,#mermaid-svg-POnk9RDjolvVgHz0 .taskTextOutside3{fill:#000}#mermaid-svg-POnk9RDjolvVgHz0 .active0,#mermaid-svg-POnk9RDjolvVgHz0 .active1,#mermaid-svg-POnk9RDjolvVgHz0 .active2,#mermaid-svg-POnk9RDjolvVgHz0 .active3{fill:#bfc7ff;stroke:#534fbc}#mermaid-svg-POnk9RDjolvVgHz0 .activeText0,#mermaid-svg-POnk9RDjolvVgHz0 .activeText1,#mermaid-svg-POnk9RDjolvVgHz0 .activeText2,#mermaid-svg-POnk9RDjolvVgHz0 .activeText3{fill:#000 !important}#mermaid-svg-POnk9RDjolvVgHz0 .done0,#mermaid-svg-POnk9RDjolvVgHz0 .done1,#mermaid-svg-POnk9RDjolvVgHz0 .done2,#mermaid-svg-POnk9RDjolvVgHz0 .done3{stroke:grey;fill:#d3d3d3;stroke-width:2}#mermaid-svg-POnk9RDjolvVgHz0 .doneText0,#mermaid-svg-POnk9RDjolvVgHz0 .doneText1,#mermaid-svg-POnk9RDjolvVgHz0 .doneText2,#mermaid-svg-POnk9RDjolvVgHz0 .doneText3{fill:#000 !important}#mermaid-svg-POnk9RDjolvVgHz0 .crit0,#mermaid-svg-POnk9RDjolvVgHz0 .crit1,#mermaid-svg-POnk9RDjolvVgHz0 .crit2,#mermaid-svg-POnk9RDjolvVgHz0 .crit3{stroke:#f88;fill:red;stroke-width:2}#mermaid-svg-POnk9RDjolvVgHz0 .activeCrit0,#mermaid-svg-POnk9RDjolvVgHz0 .activeCrit1,#mermaid-svg-POnk9RDjolvVgHz0 .activeCrit2,#mermaid-svg-POnk9RDjolvVgHz0 .activeCrit3{stroke:#f88;fill:#bfc7ff;stroke-width:2}#mermaid-svg-POnk9RDjolvVgHz0 .doneCrit0,#mermaid-svg-POnk9RDjolvVgHz0 .doneCrit1,#mermaid-svg-POnk9RDjolvVgHz0 .doneCrit2,#mermaid-svg-POnk9RDjolvVgHz0 .doneCrit3{stroke:#f88;fill:#d3d3d3;stroke-width:2;cursor:pointer;shape-rendering:crispEdges}#mermaid-svg-POnk9RDjolvVgHz0 .milestone{transform:rotate(45deg) scale(0.8, 0.8)}#mermaid-svg-POnk9RDjolvVgHz0 .milestoneText{font-style:italic}#mermaid-svg-POnk9RDjolvVgHz0 .doneCritText0,#mermaid-svg-POnk9RDjolvVgHz0 .doneCritText1,#mermaid-svg-POnk9RDjolvVgHz0 .doneCritText2,#mermaid-svg-POnk9RDjolvVgHz0 .doneCritText3{fill:#000 !important}#mermaid-svg-POnk9RDjolvVgHz0 .activeCritText0,#mermaid-svg-POnk9RDjolvVgHz0 .activeCritText1,#mermaid-svg-POnk9RDjolvVgHz0 .activeCritText2,#mermaid-svg-POnk9RDjolvVgHz0 .activeCritText3{fill:#000 !important}#mermaid-svg-POnk9RDjolvVgHz0 .titleText{text-anchor:middle;font-size:18px;fill:#000;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-POnk9RDjolvVgHz0 g.classGroup text{fill:#9370db;stroke:none;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family);font-size:10px}#mermaid-svg-POnk9RDjolvVgHz0 g.classGroup text .title{font-weight:bolder}#mermaid-svg-POnk9RDjolvVgHz0 g.clickable{cursor:pointer}#mermaid-svg-POnk9RDjolvVgHz0 g.classGroup rect{fill:#ECECFF;stroke:#9370db}#mermaid-svg-POnk9RDjolvVgHz0 g.classGroup line{stroke:#9370db;stroke-width:1}#mermaid-svg-POnk9RDjolvVgHz0 .classLabel .box{stroke:none;stroke-width:0;fill:#ECECFF;opacity:0.5}#mermaid-svg-POnk9RDjolvVgHz0 .classLabel .label{fill:#9370db;font-size:10px}#mermaid-svg-POnk9RDjolvVgHz0 .relation{stroke:#9370db;stroke-width:1;fill:none}#mermaid-svg-POnk9RDjolvVgHz0 .dashed-line{stroke-dasharray:3}#mermaid-svg-POnk9RDjolvVgHz0 #compositionStart{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-POnk9RDjolvVgHz0 #compositionEnd{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-POnk9RDjolvVgHz0 #aggregationStart{fill:#ECECFF;stroke:#9370db;stroke-width:1}#mermaid-svg-POnk9RDjolvVgHz0 #aggregationEnd{fill:#ECECFF;stroke:#9370db;stroke-width:1}#mermaid-svg-POnk9RDjolvVgHz0 #dependencyStart{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-POnk9RDjolvVgHz0 #dependencyEnd{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-POnk9RDjolvVgHz0 #extensionStart{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-POnk9RDjolvVgHz0 #extensionEnd{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-POnk9RDjolvVgHz0 .commit-id,#mermaid-svg-POnk9RDjolvVgHz0 .commit-msg,#mermaid-svg-POnk9RDjolvVgHz0 .branch-label{fill:lightgrey;color:lightgrey;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-POnk9RDjolvVgHz0 .pieTitleText{text-anchor:middle;font-size:25px;fill:#000;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-POnk9RDjolvVgHz0 .slice{font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-POnk9RDjolvVgHz0 g.stateGroup text{fill:#9370db;stroke:none;font-size:10px;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-POnk9RDjolvVgHz0 g.stateGroup text{fill:#9370db;fill:#333;stroke:none;font-size:10px}#mermaid-svg-POnk9RDjolvVgHz0 g.statediagram-cluster .cluster-label text{fill:#333}#mermaid-svg-POnk9RDjolvVgHz0 g.stateGroup .state-title{font-weight:bolder;fill:#000}#mermaid-svg-POnk9RDjolvVgHz0 g.stateGroup rect{fill:#ECECFF;stroke:#9370db}#mermaid-svg-POnk9RDjolvVgHz0 g.stateGroup line{stroke:#9370db;stroke-width:1}#mermaid-svg-POnk9RDjolvVgHz0 .transition{stroke:#9370db;stroke-width:1;fill:none}#mermaid-svg-POnk9RDjolvVgHz0 .stateGroup .composit{fill:white;border-bottom:1px}#mermaid-svg-POnk9RDjolvVgHz0 .stateGroup .alt-composit{fill:#e0e0e0;border-bottom:1px}#mermaid-svg-POnk9RDjolvVgHz0 .state-note{stroke:#aa3;fill:#fff5ad}#mermaid-svg-POnk9RDjolvVgHz0 .state-note text{fill:black;stroke:none;font-size:10px}#mermaid-svg-POnk9RDjolvVgHz0 .stateLabel .box{stroke:none;stroke-width:0;fill:#ECECFF;opacity:0.7}#mermaid-svg-POnk9RDjolvVgHz0 .edgeLabel text{fill:#333}#mermaid-svg-POnk9RDjolvVgHz0 .stateLabel text{fill:#000;font-size:10px;font-weight:bold;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-POnk9RDjolvVgHz0 .node circle.state-start{fill:black;stroke:black}#mermaid-svg-POnk9RDjolvVgHz0 .node circle.state-end{fill:black;stroke:white;stroke-width:1.5}#mermaid-svg-POnk9RDjolvVgHz0 #statediagram-barbEnd{fill:#9370db}#mermaid-svg-POnk9RDjolvVgHz0 .statediagram-cluster rect{fill:#ECECFF;stroke:#9370db;stroke-width:1px}#mermaid-svg-POnk9RDjolvVgHz0 .statediagram-cluster rect.outer{rx:5px;ry:5px}#mermaid-svg-POnk9RDjolvVgHz0 .statediagram-state .divider{stroke:#9370db}#mermaid-svg-POnk9RDjolvVgHz0 .statediagram-state .title-state{rx:5px;ry:5px}#mermaid-svg-POnk9RDjolvVgHz0 .statediagram-cluster.statediagram-cluster .inner{fill:white}#mermaid-svg-POnk9RDjolvVgHz0 .statediagram-cluster.statediagram-cluster-alt .inner{fill:#e0e0e0}#mermaid-svg-POnk9RDjolvVgHz0 .statediagram-cluster .inner{rx:0;ry:0}#mermaid-svg-POnk9RDjolvVgHz0 .statediagram-state rect.basic{rx:5px;ry:5px}#mermaid-svg-POnk9RDjolvVgHz0 .statediagram-state rect.divider{stroke-dasharray:10,10;fill:#efefef}#mermaid-svg-POnk9RDjolvVgHz0 .note-edge{stroke-dasharray:5}#mermaid-svg-POnk9RDjolvVgHz0 .statediagram-note rect{fill:#fff5ad;stroke:#aa3;stroke-width:1px;rx:0;ry:0}:root{--mermaid-font-family: '"trebuchet ms", verdana, arial';--mermaid-font-family: "Comic Sans MS", "Comic Sans", cursive}#mermaid-svg-POnk9RDjolvVgHz0 .error-icon{fill:#522}#mermaid-svg-POnk9RDjolvVgHz0 .error-text{fill:#522;stroke:#522}#mermaid-svg-POnk9RDjolvVgHz0 .edge-thickness-normal{stroke-width:2px}#mermaid-svg-POnk9RDjolvVgHz0 .edge-thickness-thick{stroke-width:3.5px}#mermaid-svg-POnk9RDjolvVgHz0 .edge-pattern-solid{stroke-dasharray:0}#mermaid-svg-POnk9RDjolvVgHz0 .edge-pattern-dashed{stroke-dasharray:3}#mermaid-svg-POnk9RDjolvVgHz0 .edge-pattern-dotted{stroke-dasharray:2}#mermaid-svg-POnk9RDjolvVgHz0 .marker{fill:#333}#mermaid-svg-POnk9RDjolvVgHz0 .marker.cross{stroke:#333} :root { --mermaid-font-family: "trebuchet ms", verdana, arial;} #mermaid-svg-POnk9RDjolvVgHz0 { color: rgba(0, 0, 0, 0.75); font: ; } Activity PhoneWindow DecorView ViewGroup View dispatchTouchEvent() true superDispatchTouchEvent() superDispatchTouchEvent() 调用dispatchTouchEvent() 调用dispatchTouchEvent() onTouchEvent()返回true dispatchTouchEvent()返回true dispatchTouchEvent()返回true dispatchTouchEvent()方法返回true Activity PhoneWindow DecorView ViewGroup View事件最终分发到View(View没有消费掉事件)
假如View的没有消费掉事件(返回false),往前回溯,那View的dispatchTouchEvent() 也会返回false,ViewGroup的dispatchTouchEvent()返回false,事件最终会通过Activity的dispatchTouchEvent()方法交由onTouchEvent()方法来处理。
#mermaid-svg-evVEW3jEfcpg7oAS .label{font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family);fill:#333;color:#333}#mermaid-svg-evVEW3jEfcpg7oAS .label text{fill:#333}#mermaid-svg-evVEW3jEfcpg7oAS .node rect,#mermaid-svg-evVEW3jEfcpg7oAS .node circle,#mermaid-svg-evVEW3jEfcpg7oAS .node ellipse,#mermaid-svg-evVEW3jEfcpg7oAS .node polygon,#mermaid-svg-evVEW3jEfcpg7oAS .node path{fill:#ECECFF;stroke:#9370db;stroke-width:1px}#mermaid-svg-evVEW3jEfcpg7oAS .node .label{text-align:center;fill:#333}#mermaid-svg-evVEW3jEfcpg7oAS .node.clickable{cursor:pointer}#mermaid-svg-evVEW3jEfcpg7oAS .arrowheadPath{fill:#333}#mermaid-svg-evVEW3jEfcpg7oAS .edgePath .path{stroke:#333;stroke-width:1.5px}#mermaid-svg-evVEW3jEfcpg7oAS .flowchart-link{stroke:#333;fill:none}#mermaid-svg-evVEW3jEfcpg7oAS .edgeLabel{background-color:#e8e8e8;text-align:center}#mermaid-svg-evVEW3jEfcpg7oAS .edgeLabel rect{opacity:0.9}#mermaid-svg-evVEW3jEfcpg7oAS .edgeLabel span{color:#333}#mermaid-svg-evVEW3jEfcpg7oAS .cluster rect{fill:#ffffde;stroke:#aa3;stroke-width:1px}#mermaid-svg-evVEW3jEfcpg7oAS .cluster text{fill:#333}#mermaid-svg-evVEW3jEfcpg7oAS div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family);font-size:12px;background:#ffffde;border:1px solid #aa3;border-radius:2px;pointer-events:none;z-index:100}#mermaid-svg-evVEW3jEfcpg7oAS .actor{stroke:#ccf;fill:#ECECFF}#mermaid-svg-evVEW3jEfcpg7oAS text.actor>tspan{fill:#000;stroke:none}#mermaid-svg-evVEW3jEfcpg7oAS .actor-line{stroke:grey}#mermaid-svg-evVEW3jEfcpg7oAS .messageLine0{stroke-width:1.5;stroke-dasharray:none;stroke:#333}#mermaid-svg-evVEW3jEfcpg7oAS .messageLine1{stroke-width:1.5;stroke-dasharray:2, 2;stroke:#333}#mermaid-svg-evVEW3jEfcpg7oAS #arrowhead path{fill:#333;stroke:#333}#mermaid-svg-evVEW3jEfcpg7oAS .sequenceNumber{fill:#fff}#mermaid-svg-evVEW3jEfcpg7oAS #sequencenumber{fill:#333}#mermaid-svg-evVEW3jEfcpg7oAS #crosshead path{fill:#333;stroke:#333}#mermaid-svg-evVEW3jEfcpg7oAS .messageText{fill:#333;stroke:#333}#mermaid-svg-evVEW3jEfcpg7oAS .labelBox{stroke:#ccf;fill:#ECECFF}#mermaid-svg-evVEW3jEfcpg7oAS .labelText,#mermaid-svg-evVEW3jEfcpg7oAS .labelText>tspan{fill:#000;stroke:none}#mermaid-svg-evVEW3jEfcpg7oAS .loopText,#mermaid-svg-evVEW3jEfcpg7oAS .loopText>tspan{fill:#000;stroke:none}#mermaid-svg-evVEW3jEfcpg7oAS .loopLine{stroke-width:2px;stroke-dasharray:2, 2;stroke:#ccf;fill:#ccf}#mermaid-svg-evVEW3jEfcpg7oAS .note{stroke:#aa3;fill:#fff5ad}#mermaid-svg-evVEW3jEfcpg7oAS .noteText,#mermaid-svg-evVEW3jEfcpg7oAS .noteText>tspan{fill:#000;stroke:none}#mermaid-svg-evVEW3jEfcpg7oAS .activation0{fill:#f4f4f4;stroke:#666}#mermaid-svg-evVEW3jEfcpg7oAS .activation1{fill:#f4f4f4;stroke:#666}#mermaid-svg-evVEW3jEfcpg7oAS .activation2{fill:#f4f4f4;stroke:#666}#mermaid-svg-evVEW3jEfcpg7oAS .mermaid-main-font{font-family:"trebuchet ms", verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-evVEW3jEfcpg7oAS .section{stroke:none;opacity:0.2}#mermaid-svg-evVEW3jEfcpg7oAS .section0{fill:rgba(102,102,255,0.49)}#mermaid-svg-evVEW3jEfcpg7oAS .section2{fill:#fff400}#mermaid-svg-evVEW3jEfcpg7oAS .section1,#mermaid-svg-evVEW3jEfcpg7oAS .section3{fill:#fff;opacity:0.2}#mermaid-svg-evVEW3jEfcpg7oAS .sectionTitle0{fill:#333}#mermaid-svg-evVEW3jEfcpg7oAS .sectionTitle1{fill:#333}#mermaid-svg-evVEW3jEfcpg7oAS .sectionTitle2{fill:#333}#mermaid-svg-evVEW3jEfcpg7oAS .sectionTitle3{fill:#333}#mermaid-svg-evVEW3jEfcpg7oAS .sectionTitle{text-anchor:start;font-size:11px;text-height:14px;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-evVEW3jEfcpg7oAS .grid .tick{stroke:#d3d3d3;opacity:0.8;shape-rendering:crispEdges}#mermaid-svg-evVEW3jEfcpg7oAS .grid .tick text{font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-evVEW3jEfcpg7oAS .grid path{stroke-width:0}#mermaid-svg-evVEW3jEfcpg7oAS .today{fill:none;stroke:red;stroke-width:2px}#mermaid-svg-evVEW3jEfcpg7oAS .task{stroke-width:2}#mermaid-svg-evVEW3jEfcpg7oAS .taskText{text-anchor:middle;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-evVEW3jEfcpg7oAS .taskText:not([font-size]){font-size:11px}#mermaid-svg-evVEW3jEfcpg7oAS .taskTextOutsideRight{fill:#000;text-anchor:start;font-size:11px;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-evVEW3jEfcpg7oAS .taskTextOutsideLeft{fill:#000;text-anchor:end;font-size:11px}#mermaid-svg-evVEW3jEfcpg7oAS .task.clickable{cursor:pointer}#mermaid-svg-evVEW3jEfcpg7oAS .taskText.clickable{cursor:pointer;fill:#003163 !important;font-weight:bold}#mermaid-svg-evVEW3jEfcpg7oAS .taskTextOutsideLeft.clickable{cursor:pointer;fill:#003163 !important;font-weight:bold}#mermaid-svg-evVEW3jEfcpg7oAS .taskTextOutsideRight.clickable{cursor:pointer;fill:#003163 !important;font-weight:bold}#mermaid-svg-evVEW3jEfcpg7oAS .taskText0,#mermaid-svg-evVEW3jEfcpg7oAS .taskText1,#mermaid-svg-evVEW3jEfcpg7oAS .taskText2,#mermaid-svg-evVEW3jEfcpg7oAS .taskText3{fill:#fff}#mermaid-svg-evVEW3jEfcpg7oAS .task0,#mermaid-svg-evVEW3jEfcpg7oAS .task1,#mermaid-svg-evVEW3jEfcpg7oAS .task2,#mermaid-svg-evVEW3jEfcpg7oAS .task3{fill:#8a90dd;stroke:#534fbc}#mermaid-svg-evVEW3jEfcpg7oAS .taskTextOutside0,#mermaid-svg-evVEW3jEfcpg7oAS .taskTextOutside2{fill:#000}#mermaid-svg-evVEW3jEfcpg7oAS .taskTextOutside1,#mermaid-svg-evVEW3jEfcpg7oAS .taskTextOutside3{fill:#000}#mermaid-svg-evVEW3jEfcpg7oAS .active0,#mermaid-svg-evVEW3jEfcpg7oAS .active1,#mermaid-svg-evVEW3jEfcpg7oAS .active2,#mermaid-svg-evVEW3jEfcpg7oAS .active3{fill:#bfc7ff;stroke:#534fbc}#mermaid-svg-evVEW3jEfcpg7oAS .activeText0,#mermaid-svg-evVEW3jEfcpg7oAS .activeText1,#mermaid-svg-evVEW3jEfcpg7oAS .activeText2,#mermaid-svg-evVEW3jEfcpg7oAS .activeText3{fill:#000 !important}#mermaid-svg-evVEW3jEfcpg7oAS .done0,#mermaid-svg-evVEW3jEfcpg7oAS .done1,#mermaid-svg-evVEW3jEfcpg7oAS .done2,#mermaid-svg-evVEW3jEfcpg7oAS .done3{stroke:grey;fill:#d3d3d3;stroke-width:2}#mermaid-svg-evVEW3jEfcpg7oAS .doneText0,#mermaid-svg-evVEW3jEfcpg7oAS .doneText1,#mermaid-svg-evVEW3jEfcpg7oAS .doneText2,#mermaid-svg-evVEW3jEfcpg7oAS .doneText3{fill:#000 !important}#mermaid-svg-evVEW3jEfcpg7oAS .crit0,#mermaid-svg-evVEW3jEfcpg7oAS .crit1,#mermaid-svg-evVEW3jEfcpg7oAS .crit2,#mermaid-svg-evVEW3jEfcpg7oAS .crit3{stroke:#f88;fill:red;stroke-width:2}#mermaid-svg-evVEW3jEfcpg7oAS .activeCrit0,#mermaid-svg-evVEW3jEfcpg7oAS .activeCrit1,#mermaid-svg-evVEW3jEfcpg7oAS .activeCrit2,#mermaid-svg-evVEW3jEfcpg7oAS .activeCrit3{stroke:#f88;fill:#bfc7ff;stroke-width:2}#mermaid-svg-evVEW3jEfcpg7oAS .doneCrit0,#mermaid-svg-evVEW3jEfcpg7oAS .doneCrit1,#mermaid-svg-evVEW3jEfcpg7oAS .doneCrit2,#mermaid-svg-evVEW3jEfcpg7oAS .doneCrit3{stroke:#f88;fill:#d3d3d3;stroke-width:2;cursor:pointer;shape-rendering:crispEdges}#mermaid-svg-evVEW3jEfcpg7oAS .milestone{transform:rotate(45deg) scale(0.8, 0.8)}#mermaid-svg-evVEW3jEfcpg7oAS .milestoneText{font-style:italic}#mermaid-svg-evVEW3jEfcpg7oAS .doneCritText0,#mermaid-svg-evVEW3jEfcpg7oAS .doneCritText1,#mermaid-svg-evVEW3jEfcpg7oAS .doneCritText2,#mermaid-svg-evVEW3jEfcpg7oAS .doneCritText3{fill:#000 !important}#mermaid-svg-evVEW3jEfcpg7oAS .activeCritText0,#mermaid-svg-evVEW3jEfcpg7oAS .activeCritText1,#mermaid-svg-evVEW3jEfcpg7oAS .activeCritText2,#mermaid-svg-evVEW3jEfcpg7oAS .activeCritText3{fill:#000 !important}#mermaid-svg-evVEW3jEfcpg7oAS .titleText{text-anchor:middle;font-size:18px;fill:#000;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-evVEW3jEfcpg7oAS g.classGroup text{fill:#9370db;stroke:none;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family);font-size:10px}#mermaid-svg-evVEW3jEfcpg7oAS g.classGroup text .title{font-weight:bolder}#mermaid-svg-evVEW3jEfcpg7oAS g.clickable{cursor:pointer}#mermaid-svg-evVEW3jEfcpg7oAS g.classGroup rect{fill:#ECECFF;stroke:#9370db}#mermaid-svg-evVEW3jEfcpg7oAS g.classGroup line{stroke:#9370db;stroke-width:1}#mermaid-svg-evVEW3jEfcpg7oAS .classLabel .box{stroke:none;stroke-width:0;fill:#ECECFF;opacity:0.5}#mermaid-svg-evVEW3jEfcpg7oAS .classLabel .label{fill:#9370db;font-size:10px}#mermaid-svg-evVEW3jEfcpg7oAS .relation{stroke:#9370db;stroke-width:1;fill:none}#mermaid-svg-evVEW3jEfcpg7oAS .dashed-line{stroke-dasharray:3}#mermaid-svg-evVEW3jEfcpg7oAS #compositionStart{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-evVEW3jEfcpg7oAS #compositionEnd{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-evVEW3jEfcpg7oAS #aggregationStart{fill:#ECECFF;stroke:#9370db;stroke-width:1}#mermaid-svg-evVEW3jEfcpg7oAS #aggregationEnd{fill:#ECECFF;stroke:#9370db;stroke-width:1}#mermaid-svg-evVEW3jEfcpg7oAS #dependencyStart{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-evVEW3jEfcpg7oAS #dependencyEnd{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-evVEW3jEfcpg7oAS #extensionStart{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-evVEW3jEfcpg7oAS #extensionEnd{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-evVEW3jEfcpg7oAS .commit-id,#mermaid-svg-evVEW3jEfcpg7oAS .commit-msg,#mermaid-svg-evVEW3jEfcpg7oAS .branch-label{fill:lightgrey;color:lightgrey;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-evVEW3jEfcpg7oAS .pieTitleText{text-anchor:middle;font-size:25px;fill:#000;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-evVEW3jEfcpg7oAS .slice{font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-evVEW3jEfcpg7oAS g.stateGroup text{fill:#9370db;stroke:none;font-size:10px;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-evVEW3jEfcpg7oAS g.stateGroup text{fill:#9370db;fill:#333;stroke:none;font-size:10px}#mermaid-svg-evVEW3jEfcpg7oAS g.statediagram-cluster .cluster-label text{fill:#333}#mermaid-svg-evVEW3jEfcpg7oAS g.stateGroup .state-title{font-weight:bolder;fill:#000}#mermaid-svg-evVEW3jEfcpg7oAS g.stateGroup rect{fill:#ECECFF;stroke:#9370db}#mermaid-svg-evVEW3jEfcpg7oAS g.stateGroup line{stroke:#9370db;stroke-width:1}#mermaid-svg-evVEW3jEfcpg7oAS .transition{stroke:#9370db;stroke-width:1;fill:none}#mermaid-svg-evVEW3jEfcpg7oAS .stateGroup .composit{fill:white;border-bottom:1px}#mermaid-svg-evVEW3jEfcpg7oAS .stateGroup .alt-composit{fill:#e0e0e0;border-bottom:1px}#mermaid-svg-evVEW3jEfcpg7oAS .state-note{stroke:#aa3;fill:#fff5ad}#mermaid-svg-evVEW3jEfcpg7oAS .state-note text{fill:black;stroke:none;font-size:10px}#mermaid-svg-evVEW3jEfcpg7oAS .stateLabel .box{stroke:none;stroke-width:0;fill:#ECECFF;opacity:0.7}#mermaid-svg-evVEW3jEfcpg7oAS .edgeLabel text{fill:#333}#mermaid-svg-evVEW3jEfcpg7oAS .stateLabel text{fill:#000;font-size:10px;font-weight:bold;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-evVEW3jEfcpg7oAS .node circle.state-start{fill:black;stroke:black}#mermaid-svg-evVEW3jEfcpg7oAS .node circle.state-end{fill:black;stroke:white;stroke-width:1.5}#mermaid-svg-evVEW3jEfcpg7oAS #statediagram-barbEnd{fill:#9370db}#mermaid-svg-evVEW3jEfcpg7oAS .statediagram-cluster rect{fill:#ECECFF;stroke:#9370db;stroke-width:1px}#mermaid-svg-evVEW3jEfcpg7oAS .statediagram-cluster rect.outer{rx:5px;ry:5px}#mermaid-svg-evVEW3jEfcpg7oAS .statediagram-state .divider{stroke:#9370db}#mermaid-svg-evVEW3jEfcpg7oAS .statediagram-state .title-state{rx:5px;ry:5px}#mermaid-svg-evVEW3jEfcpg7oAS .statediagram-cluster.statediagram-cluster .inner{fill:white}#mermaid-svg-evVEW3jEfcpg7oAS .statediagram-cluster.statediagram-cluster-alt .inner{fill:#e0e0e0}#mermaid-svg-evVEW3jEfcpg7oAS .statediagram-cluster .inner{rx:0;ry:0}#mermaid-svg-evVEW3jEfcpg7oAS .statediagram-state rect.basic{rx:5px;ry:5px}#mermaid-svg-evVEW3jEfcpg7oAS .statediagram-state rect.divider{stroke-dasharray:10,10;fill:#efefef}#mermaid-svg-evVEW3jEfcpg7oAS .note-edge{stroke-dasharray:5}#mermaid-svg-evVEW3jEfcpg7oAS .statediagram-note rect{fill:#fff5ad;stroke:#aa3;stroke-width:1px;rx:0;ry:0}:root{--mermaid-font-family: '"trebuchet ms", verdana, arial';--mermaid-font-family: "Comic Sans MS", "Comic Sans", cursive}#mermaid-svg-evVEW3jEfcpg7oAS .error-icon{fill:#522}#mermaid-svg-evVEW3jEfcpg7oAS .error-text{fill:#522;stroke:#522}#mermaid-svg-evVEW3jEfcpg7oAS .edge-thickness-normal{stroke-width:2px}#mermaid-svg-evVEW3jEfcpg7oAS .edge-thickness-thick{stroke-width:3.5px}#mermaid-svg-evVEW3jEfcpg7oAS .edge-pattern-solid{stroke-dasharray:0}#mermaid-svg-evVEW3jEfcpg7oAS .edge-pattern-dashed{stroke-dasharray:3}#mermaid-svg-evVEW3jEfcpg7oAS .edge-pattern-dotted{stroke-dasharray:2}#mermaid-svg-evVEW3jEfcpg7oAS .marker{fill:#333}#mermaid-svg-evVEW3jEfcpg7oAS .marker.cross{stroke:#333} :root { --mermaid-font-family: "trebuchet ms", verdana, arial;} #mermaid-svg-evVEW3jEfcpg7oAS { color: rgba(0, 0, 0, 0.75); font: ; } Activity PhoneWindow DecorView ViewGroup View dispatchTouchEvent() true superDispatchTouchEvent() superDispatchTouchEvent() 调用dispatchTouchEvent() 调用dispatchTouchEvent() onTouchEvent()返回false dispatchTouchEvent()返回false dispatchTouchEvent()返回false dispatchTouchEvent()方法返回false dispatchTouchEvent() Activity PhoneWindow DecorView ViewGroup View事件被VIewGroup拦截(ViewGroup消费掉事件):
当然上述的图默认表示的是ViewGroup的onInterceptTouchEvent()返回false的逻辑。假如ViewGroup的onInterceptTouchEvent()返回true。那代码很明显就要走ViewGroup的onTouchEvent()方法,此时如果子类重写了onTouchEvent()方法并消费了事件,方法调用关系如下图:
#mermaid-svg-XMsDP5hzKrbSLAzX .label{font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family);fill:#333;color:#333}#mermaid-svg-XMsDP5hzKrbSLAzX .label text{fill:#333}#mermaid-svg-XMsDP5hzKrbSLAzX .node rect,#mermaid-svg-XMsDP5hzKrbSLAzX .node circle,#mermaid-svg-XMsDP5hzKrbSLAzX .node ellipse,#mermaid-svg-XMsDP5hzKrbSLAzX .node polygon,#mermaid-svg-XMsDP5hzKrbSLAzX .node path{fill:#ECECFF;stroke:#9370db;stroke-width:1px}#mermaid-svg-XMsDP5hzKrbSLAzX .node .label{text-align:center;fill:#333}#mermaid-svg-XMsDP5hzKrbSLAzX .node.clickable{cursor:pointer}#mermaid-svg-XMsDP5hzKrbSLAzX .arrowheadPath{fill:#333}#mermaid-svg-XMsDP5hzKrbSLAzX .edgePath .path{stroke:#333;stroke-width:1.5px}#mermaid-svg-XMsDP5hzKrbSLAzX .flowchart-link{stroke:#333;fill:none}#mermaid-svg-XMsDP5hzKrbSLAzX .edgeLabel{background-color:#e8e8e8;text-align:center}#mermaid-svg-XMsDP5hzKrbSLAzX .edgeLabel rect{opacity:0.9}#mermaid-svg-XMsDP5hzKrbSLAzX .edgeLabel span{color:#333}#mermaid-svg-XMsDP5hzKrbSLAzX .cluster rect{fill:#ffffde;stroke:#aa3;stroke-width:1px}#mermaid-svg-XMsDP5hzKrbSLAzX .cluster text{fill:#333}#mermaid-svg-XMsDP5hzKrbSLAzX div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family);font-size:12px;background:#ffffde;border:1px solid #aa3;border-radius:2px;pointer-events:none;z-index:100}#mermaid-svg-XMsDP5hzKrbSLAzX .actor{stroke:#ccf;fill:#ECECFF}#mermaid-svg-XMsDP5hzKrbSLAzX text.actor>tspan{fill:#000;stroke:none}#mermaid-svg-XMsDP5hzKrbSLAzX .actor-line{stroke:grey}#mermaid-svg-XMsDP5hzKrbSLAzX .messageLine0{stroke-width:1.5;stroke-dasharray:none;stroke:#333}#mermaid-svg-XMsDP5hzKrbSLAzX .messageLine1{stroke-width:1.5;stroke-dasharray:2, 2;stroke:#333}#mermaid-svg-XMsDP5hzKrbSLAzX #arrowhead path{fill:#333;stroke:#333}#mermaid-svg-XMsDP5hzKrbSLAzX .sequenceNumber{fill:#fff}#mermaid-svg-XMsDP5hzKrbSLAzX #sequencenumber{fill:#333}#mermaid-svg-XMsDP5hzKrbSLAzX #crosshead path{fill:#333;stroke:#333}#mermaid-svg-XMsDP5hzKrbSLAzX .messageText{fill:#333;stroke:#333}#mermaid-svg-XMsDP5hzKrbSLAzX .labelBox{stroke:#ccf;fill:#ECECFF}#mermaid-svg-XMsDP5hzKrbSLAzX .labelText,#mermaid-svg-XMsDP5hzKrbSLAzX .labelText>tspan{fill:#000;stroke:none}#mermaid-svg-XMsDP5hzKrbSLAzX .loopText,#mermaid-svg-XMsDP5hzKrbSLAzX .loopText>tspan{fill:#000;stroke:none}#mermaid-svg-XMsDP5hzKrbSLAzX .loopLine{stroke-width:2px;stroke-dasharray:2, 2;stroke:#ccf;fill:#ccf}#mermaid-svg-XMsDP5hzKrbSLAzX .note{stroke:#aa3;fill:#fff5ad}#mermaid-svg-XMsDP5hzKrbSLAzX .noteText,#mermaid-svg-XMsDP5hzKrbSLAzX .noteText>tspan{fill:#000;stroke:none}#mermaid-svg-XMsDP5hzKrbSLAzX .activation0{fill:#f4f4f4;stroke:#666}#mermaid-svg-XMsDP5hzKrbSLAzX .activation1{fill:#f4f4f4;stroke:#666}#mermaid-svg-XMsDP5hzKrbSLAzX .activation2{fill:#f4f4f4;stroke:#666}#mermaid-svg-XMsDP5hzKrbSLAzX .mermaid-main-font{font-family:"trebuchet ms", verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-XMsDP5hzKrbSLAzX .section{stroke:none;opacity:0.2}#mermaid-svg-XMsDP5hzKrbSLAzX .section0{fill:rgba(102,102,255,0.49)}#mermaid-svg-XMsDP5hzKrbSLAzX .section2{fill:#fff400}#mermaid-svg-XMsDP5hzKrbSLAzX .section1,#mermaid-svg-XMsDP5hzKrbSLAzX .section3{fill:#fff;opacity:0.2}#mermaid-svg-XMsDP5hzKrbSLAzX .sectionTitle0{fill:#333}#mermaid-svg-XMsDP5hzKrbSLAzX .sectionTitle1{fill:#333}#mermaid-svg-XMsDP5hzKrbSLAzX .sectionTitle2{fill:#333}#mermaid-svg-XMsDP5hzKrbSLAzX .sectionTitle3{fill:#333}#mermaid-svg-XMsDP5hzKrbSLAzX .sectionTitle{text-anchor:start;font-size:11px;text-height:14px;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-XMsDP5hzKrbSLAzX .grid .tick{stroke:#d3d3d3;opacity:0.8;shape-rendering:crispEdges}#mermaid-svg-XMsDP5hzKrbSLAzX .grid .tick text{font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-XMsDP5hzKrbSLAzX .grid path{stroke-width:0}#mermaid-svg-XMsDP5hzKrbSLAzX .today{fill:none;stroke:red;stroke-width:2px}#mermaid-svg-XMsDP5hzKrbSLAzX .task{stroke-width:2}#mermaid-svg-XMsDP5hzKrbSLAzX .taskText{text-anchor:middle;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-XMsDP5hzKrbSLAzX .taskText:not([font-size]){font-size:11px}#mermaid-svg-XMsDP5hzKrbSLAzX .taskTextOutsideRight{fill:#000;text-anchor:start;font-size:11px;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-XMsDP5hzKrbSLAzX .taskTextOutsideLeft{fill:#000;text-anchor:end;font-size:11px}#mermaid-svg-XMsDP5hzKrbSLAzX .task.clickable{cursor:pointer}#mermaid-svg-XMsDP5hzKrbSLAzX .taskText.clickable{cursor:pointer;fill:#003163 !important;font-weight:bold}#mermaid-svg-XMsDP5hzKrbSLAzX .taskTextOutsideLeft.clickable{cursor:pointer;fill:#003163 !important;font-weight:bold}#mermaid-svg-XMsDP5hzKrbSLAzX .taskTextOutsideRight.clickable{cursor:pointer;fill:#003163 !important;font-weight:bold}#mermaid-svg-XMsDP5hzKrbSLAzX .taskText0,#mermaid-svg-XMsDP5hzKrbSLAzX .taskText1,#mermaid-svg-XMsDP5hzKrbSLAzX .taskText2,#mermaid-svg-XMsDP5hzKrbSLAzX .taskText3{fill:#fff}#mermaid-svg-XMsDP5hzKrbSLAzX .task0,#mermaid-svg-XMsDP5hzKrbSLAzX .task1,#mermaid-svg-XMsDP5hzKrbSLAzX .task2,#mermaid-svg-XMsDP5hzKrbSLAzX .task3{fill:#8a90dd;stroke:#534fbc}#mermaid-svg-XMsDP5hzKrbSLAzX .taskTextOutside0,#mermaid-svg-XMsDP5hzKrbSLAzX .taskTextOutside2{fill:#000}#mermaid-svg-XMsDP5hzKrbSLAzX .taskTextOutside1,#mermaid-svg-XMsDP5hzKrbSLAzX .taskTextOutside3{fill:#000}#mermaid-svg-XMsDP5hzKrbSLAzX .active0,#mermaid-svg-XMsDP5hzKrbSLAzX .active1,#mermaid-svg-XMsDP5hzKrbSLAzX .active2,#mermaid-svg-XMsDP5hzKrbSLAzX .active3{fill:#bfc7ff;stroke:#534fbc}#mermaid-svg-XMsDP5hzKrbSLAzX .activeText0,#mermaid-svg-XMsDP5hzKrbSLAzX .activeText1,#mermaid-svg-XMsDP5hzKrbSLAzX .activeText2,#mermaid-svg-XMsDP5hzKrbSLAzX .activeText3{fill:#000 !important}#mermaid-svg-XMsDP5hzKrbSLAzX .done0,#mermaid-svg-XMsDP5hzKrbSLAzX .done1,#mermaid-svg-XMsDP5hzKrbSLAzX .done2,#mermaid-svg-XMsDP5hzKrbSLAzX .done3{stroke:grey;fill:#d3d3d3;stroke-width:2}#mermaid-svg-XMsDP5hzKrbSLAzX .doneText0,#mermaid-svg-XMsDP5hzKrbSLAzX .doneText1,#mermaid-svg-XMsDP5hzKrbSLAzX .doneText2,#mermaid-svg-XMsDP5hzKrbSLAzX .doneText3{fill:#000 !important}#mermaid-svg-XMsDP5hzKrbSLAzX .crit0,#mermaid-svg-XMsDP5hzKrbSLAzX .crit1,#mermaid-svg-XMsDP5hzKrbSLAzX .crit2,#mermaid-svg-XMsDP5hzKrbSLAzX .crit3{stroke:#f88;fill:red;stroke-width:2}#mermaid-svg-XMsDP5hzKrbSLAzX .activeCrit0,#mermaid-svg-XMsDP5hzKrbSLAzX .activeCrit1,#mermaid-svg-XMsDP5hzKrbSLAzX .activeCrit2,#mermaid-svg-XMsDP5hzKrbSLAzX .activeCrit3{stroke:#f88;fill:#bfc7ff;stroke-width:2}#mermaid-svg-XMsDP5hzKrbSLAzX .doneCrit0,#mermaid-svg-XMsDP5hzKrbSLAzX .doneCrit1,#mermaid-svg-XMsDP5hzKrbSLAzX .doneCrit2,#mermaid-svg-XMsDP5hzKrbSLAzX .doneCrit3{stroke:#f88;fill:#d3d3d3;stroke-width:2;cursor:pointer;shape-rendering:crispEdges}#mermaid-svg-XMsDP5hzKrbSLAzX .milestone{transform:rotate(45deg) scale(0.8, 0.8)}#mermaid-svg-XMsDP5hzKrbSLAzX .milestoneText{font-style:italic}#mermaid-svg-XMsDP5hzKrbSLAzX .doneCritText0,#mermaid-svg-XMsDP5hzKrbSLAzX .doneCritText1,#mermaid-svg-XMsDP5hzKrbSLAzX .doneCritText2,#mermaid-svg-XMsDP5hzKrbSLAzX .doneCritText3{fill:#000 !important}#mermaid-svg-XMsDP5hzKrbSLAzX .activeCritText0,#mermaid-svg-XMsDP5hzKrbSLAzX .activeCritText1,#mermaid-svg-XMsDP5hzKrbSLAzX .activeCritText2,#mermaid-svg-XMsDP5hzKrbSLAzX .activeCritText3{fill:#000 !important}#mermaid-svg-XMsDP5hzKrbSLAzX .titleText{text-anchor:middle;font-size:18px;fill:#000;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-XMsDP5hzKrbSLAzX g.classGroup text{fill:#9370db;stroke:none;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family);font-size:10px}#mermaid-svg-XMsDP5hzKrbSLAzX g.classGroup text .title{font-weight:bolder}#mermaid-svg-XMsDP5hzKrbSLAzX g.clickable{cursor:pointer}#mermaid-svg-XMsDP5hzKrbSLAzX g.classGroup rect{fill:#ECECFF;stroke:#9370db}#mermaid-svg-XMsDP5hzKrbSLAzX g.classGroup line{stroke:#9370db;stroke-width:1}#mermaid-svg-XMsDP5hzKrbSLAzX .classLabel .box{stroke:none;stroke-width:0;fill:#ECECFF;opacity:0.5}#mermaid-svg-XMsDP5hzKrbSLAzX .classLabel .label{fill:#9370db;font-size:10px}#mermaid-svg-XMsDP5hzKrbSLAzX .relation{stroke:#9370db;stroke-width:1;fill:none}#mermaid-svg-XMsDP5hzKrbSLAzX .dashed-line{stroke-dasharray:3}#mermaid-svg-XMsDP5hzKrbSLAzX #compositionStart{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-XMsDP5hzKrbSLAzX #compositionEnd{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-XMsDP5hzKrbSLAzX #aggregationStart{fill:#ECECFF;stroke:#9370db;stroke-width:1}#mermaid-svg-XMsDP5hzKrbSLAzX #aggregationEnd{fill:#ECECFF;stroke:#9370db;stroke-width:1}#mermaid-svg-XMsDP5hzKrbSLAzX #dependencyStart{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-XMsDP5hzKrbSLAzX #dependencyEnd{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-XMsDP5hzKrbSLAzX #extensionStart{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-XMsDP5hzKrbSLAzX #extensionEnd{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-XMsDP5hzKrbSLAzX .commit-id,#mermaid-svg-XMsDP5hzKrbSLAzX .commit-msg,#mermaid-svg-XMsDP5hzKrbSLAzX .branch-label{fill:lightgrey;color:lightgrey;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-XMsDP5hzKrbSLAzX .pieTitleText{text-anchor:middle;font-size:25px;fill:#000;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-XMsDP5hzKrbSLAzX .slice{font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-XMsDP5hzKrbSLAzX g.stateGroup text{fill:#9370db;stroke:none;font-size:10px;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-XMsDP5hzKrbSLAzX g.stateGroup text{fill:#9370db;fill:#333;stroke:none;font-size:10px}#mermaid-svg-XMsDP5hzKrbSLAzX g.statediagram-cluster .cluster-label text{fill:#333}#mermaid-svg-XMsDP5hzKrbSLAzX g.stateGroup .state-title{font-weight:bolder;fill:#000}#mermaid-svg-XMsDP5hzKrbSLAzX g.stateGroup rect{fill:#ECECFF;stroke:#9370db}#mermaid-svg-XMsDP5hzKrbSLAzX g.stateGroup line{stroke:#9370db;stroke-width:1}#mermaid-svg-XMsDP5hzKrbSLAzX .transition{stroke:#9370db;stroke-width:1;fill:none}#mermaid-svg-XMsDP5hzKrbSLAzX .stateGroup .composit{fill:white;border-bottom:1px}#mermaid-svg-XMsDP5hzKrbSLAzX .stateGroup .alt-composit{fill:#e0e0e0;border-bottom:1px}#mermaid-svg-XMsDP5hzKrbSLAzX .state-note{stroke:#aa3;fill:#fff5ad}#mermaid-svg-XMsDP5hzKrbSLAzX .state-note text{fill:black;stroke:none;font-size:10px}#mermaid-svg-XMsDP5hzKrbSLAzX .stateLabel .box{stroke:none;stroke-width:0;fill:#ECECFF;opacity:0.7}#mermaid-svg-XMsDP5hzKrbSLAzX .edgeLabel text{fill:#333}#mermaid-svg-XMsDP5hzKrbSLAzX .stateLabel text{fill:#000;font-size:10px;font-weight:bold;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-XMsDP5hzKrbSLAzX .node circle.state-start{fill:black;stroke:black}#mermaid-svg-XMsDP5hzKrbSLAzX .node circle.state-end{fill:black;stroke:white;stroke-width:1.5}#mermaid-svg-XMsDP5hzKrbSLAzX #statediagram-barbEnd{fill:#9370db}#mermaid-svg-XMsDP5hzKrbSLAzX .statediagram-cluster rect{fill:#ECECFF;stroke:#9370db;stroke-width:1px}#mermaid-svg-XMsDP5hzKrbSLAzX .statediagram-cluster rect.outer{rx:5px;ry:5px}#mermaid-svg-XMsDP5hzKrbSLAzX .statediagram-state .divider{stroke:#9370db}#mermaid-svg-XMsDP5hzKrbSLAzX .statediagram-state .title-state{rx:5px;ry:5px}#mermaid-svg-XMsDP5hzKrbSLAzX .statediagram-cluster.statediagram-cluster .inner{fill:white}#mermaid-svg-XMsDP5hzKrbSLAzX .statediagram-cluster.statediagram-cluster-alt .inner{fill:#e0e0e0}#mermaid-svg-XMsDP5hzKrbSLAzX .statediagram-cluster .inner{rx:0;ry:0}#mermaid-svg-XMsDP5hzKrbSLAzX .statediagram-state rect.basic{rx:5px;ry:5px}#mermaid-svg-XMsDP5hzKrbSLAzX .statediagram-state rect.divider{stroke-dasharray:10,10;fill:#efefef}#mermaid-svg-XMsDP5hzKrbSLAzX .note-edge{stroke-dasharray:5}#mermaid-svg-XMsDP5hzKrbSLAzX .statediagram-note rect{fill:#fff5ad;stroke:#aa3;stroke-width:1px;rx:0;ry:0}:root{--mermaid-font-family: '"trebuchet ms", verdana, arial';--mermaid-font-family: "Comic Sans MS", "Comic Sans", cursive}#mermaid-svg-XMsDP5hzKrbSLAzX .error-icon{fill:#522}#mermaid-svg-XMsDP5hzKrbSLAzX .error-text{fill:#522;stroke:#522}#mermaid-svg-XMsDP5hzKrbSLAzX .edge-thickness-normal{stroke-width:2px}#mermaid-svg-XMsDP5hzKrbSLAzX .edge-thickness-thick{stroke-width:3.5px}#mermaid-svg-XMsDP5hzKrbSLAzX .edge-pattern-solid{stroke-dasharray:0}#mermaid-svg-XMsDP5hzKrbSLAzX .edge-pattern-dashed{stroke-dasharray:3}#mermaid-svg-XMsDP5hzKrbSLAzX .edge-pattern-dotted{stroke-dasharray:2}#mermaid-svg-XMsDP5hzKrbSLAzX .marker{fill:#333}#mermaid-svg-XMsDP5hzKrbSLAzX .marker.cross{stroke:#333} :root { --mermaid-font-family: "trebuchet ms", verdana, arial;} #mermaid-svg-XMsDP5hzKrbSLAzX { color: rgba(0, 0, 0, 0.75); font: ; } Activity PhoneWindow DecorView ViewGroup dispatchTouchEvent() true superDispatchTouchEvent() superDispatchTouchEvent() 调用dispatchTouchEvent() onInterceptTouchEvent()返回true onTouchEvent() 返回true dispatchTouchEvent()返回true dispatchTouchEvent()方法返回true Activity PhoneWindow DecorView ViewGroup小结一下
假如ViewGroup拦截了View的事件,那么最终事件就被分发到ViewGroup的onTouchEvent() 方法中。 如果没有拦截,事件就被分发到了View的onTouchEvent()方法中。 此时的View默认是可以点击的(比如Button),那子View就默认消费了事件。如果子View不能点击(比如TextView),那子View就不会消费事件。
还剩下一个问题,之前说View要么不处理事件,要么就是整个事件序列一起处理,这部分是如何实现的? 这部分源码只看了个大概(没看太懂…)。 大致的流程: 在ViewGroup的dispatchTouchEvent() 方法中。如果接收到的事件是ACTION_DOWN时,会将处理DOWN事件的子View 保存到mFirstTouchTarget变量中。后面的MOVE,UP事件来的时候,通过调用dispatchTransformedTouchEvent(child)方法来执行child的dispatchTouchEvent()方法。
Click与LongClick事件是如何进行判断的呢?
Click事件对应较短时间内(<0.5s)的一次DOWN和UP事件。 LongClick事件对应较长事件(>0.5s)的一次DOWN事件和UP事件。
而DOWN跟UP事件都是发生在View的onTouchEvent()方法中。因此可以初步判断Click事件与LongClick事件都可以在View的onTouchEvent()事件中找到调用链。
public boolean onTouchEvent(MotionEvent event) { final boolean clickable = ((viewFlags & CLICKABLE) == CLICKABLE || (viewFlags & LONG_CLICKABLE) == LONG_CLICKABLE) || (viewFlags & CONTEXT_CLICKABLE) == CONTEXT_CLICKABLE; if (clickable ) { switch (action) { case MotionEvent.ACTION_UP: //一系列操作 if ((mPrivateFlags & PFLAG_PRESSED) != 0 || prepressed) { //一系列操作 if (!mHasPerformedLongPress && !mIgnoreNextUpEvent) { //一系列操作 if (!focusTaken) { // Use a Runnable and post this rather than calling // performClick directly. This lets other visual state // of the view update before click actions start. if (mPerformClick == null) { mPerformClick = new PerformClick(); } if (!post(mPerformClick)) { performClickInternal(); } } } //一系列操作 break; case MotionEvent.ACTION_DOWN: //一系列操作 if (!clickable) { checkForLongClick(0, x, y); break; } //一系列操作 break; case MotionEvent.ACTION_CANCEL: //一系列操作 break; case MotionEvent.ACTION_MOVE: //一系列操作 break; } return true; } return false; }通过上面的代码可以看到在UP事件中有一个mPerformClick对象;在DOWN事件中有个checkForLongClick()方法。通过名字我们似乎可以看出UP事件处理的Click相关的回调。而DOWN事件处理的LongClick相关的回调。
继续往下跟代码发现确实如此。在View的performClickInternal()方法
private boolean performClickInternal() { // Must notify autofill manager before performing the click actions to avoid scenarios where // the app has a click listener that changes the state of views the autofill service might // be interested on. notifyAutofillManagerOnClick(); return performClick(); }performClick() 方法
public boolean performClick() { // We still need to call this method to handle the cases where performClick() was called // externally, instead of through performClickInternal() notifyAutofillManagerOnClick(); final boolean result; final ListenerInfo li = mListenerInfo; if (li != null && li.mOnClickListener != null) { playSoundEffect(SoundEffectConstants.CLICK); li.mOnClickListener.onClick(this); result = true; } else { result = false; } sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_CLICKED); notifyEnterOrExitForAutoFillIfNeeded(true); return result; }我们看到了li.mOnClickListener.onClick(this);
同样在也是在View的checkForLongClick()方法:
private void checkForLongClick(int delayOffset, float x, float y) { if ((mViewFlags & LONG_CLICKABLE) == LONG_CLICKABLE || (mViewFlags & TOOLTIP) == TOOLTIP) { mHasPerformedLongPress = false; if (mPendingCheckForLongPress == null) { mPendingCheckForLongPress = new CheckForLongPress(); } mPendingCheckForLongPress.setAnchor(x, y); mPendingCheckForLongPress.rememberWindowAttachCount(); mPendingCheckForLongPress.rememberPressedState(); postDelayed(mPendingCheckForLongPress, ViewConfiguration.getLongPressTimeout() - delayOffset); } }CheckForLongPress() 对象中
private final class CheckForLongPress implements Runnable { private int mOriginalWindowAttachCount; private float mX; private float mY; private boolean mOriginalPressedState; @Override public void run() { if ((mOriginalPressedState == isPressed()) && (mParent != null) && mOriginalWindowAttachCount == mWindowAttachCount) { if (performLongClick(mX, mY)) { mHasPerformedLongPress = true; } } } //... }performLongClick()方法。继续往下多跟几个方法
private boolean performLongClickInternal(float x, float y) { sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_LONG_CLICKED); boolean handled = false; final ListenerInfo li = mListenerInfo; if (li != null && li.mOnLongClickListener != null) { handled = li.mOnLongClickListener.onLongClick(View.this); } //... }最终可以看到li.mOnLongClickListener.onLongClick() 这一行代码。 基本可以验证我们上面的猜想。 在View的onTouchEvent() 方法的UP事件中调用了Click事件,在DOWN事件中调用了LongClick事件。
引用:
https://blog.csdn.net/weixin_41101173/article/details/79685305?utm_source=blogxgwz1 https://www.gcssloop.com/customview/dispatch-touchevent-theory https://zhuanlan.zhihu.com/p/27608989 https://blog.csdn.net/guolin_blog/article/details/9097463 https://blog.csdn.net/guolin_blog/article/details/9153747