第一次认真写博客,各位大哥大姐,弟弟妹妹请指教。(如有需要讨论的地方,尽可以评论)
首先附上美国大牛Dave Smith的PPT--Mastering Android Touch System的相关部分,以及自己的翻译(翻译的不好请尽情指出)
• Each user touch event is wrapped up as a MotionEvent(每一个触摸事件被封装成一个MotionEvent类)
• Describes user's current action(描述用户的当前动作的有以下常量)
-ACTION_DOWN
– ACTION_UP
– ACTION_MOVE
–ACTION_POINTER_DOWN(当第一根之后的手指按下用此常量表示)
– ACTION_POINTER_UP(当第一根之后的常量按下用此常量表示)
– ACTION_CANCEL(此处不太清楚,哪位大神知道可告诉我)
• Event metadata included(每一个触摸事件包括触摸的信息有触摸坐标,触摸的手指数,触摸的事件)
– Touch location
– Number of pointers (fingers)
– Event time
• A “gesture” is defined as beginning with ACTION_DOWN and endingwith ACTION_UP.(一个手势以ACTION_DOWN开始,以ACTION_UP结束
(鉴于大家英语应该不错我就不逐句翻译了)
Events start at the Activiry with dispatchTouchEvent()
• Events flow top down through views(事件自顶向下通过视图)
– Parents (ViewGroups) dispatch events to their children
– Can intercept events at any time(父视图可在任何时候拦截传向其子视图的事件)
• Events flow down the chain (and back up) until consumed
– Views must declare interest by consuming ACTION_DOWN(视图必须对ACTION_DOWN感兴趣,即当action为ACTION_DOWN时在onTouchEvent中返回true,才能对之后的事件进行处理)
– Further events not delivered for efficiency
• Any unconsumed events end at the Activity with onTouchEvent()
• Optional External OnTouchListener can intercept touches on any View/ViewGroup(使用视图或视图容器的setOnTouchListener()拦截任何触摸事件,此方法优先于onTouchEvent)
对于以下两点总的说一下流程
触屏事件首先传到Activity的dispatchTouchEvent中再将其传给Activity的根布局文件(为一个ViewGroup的子类)的dispatchTouchEvent,
然后再传递给根布局文件onInterceptionTouchEvent(),
如果返回true,则将事件拦截,传递给当前ViewGroup的onTouchEvent
若返回false,ViewGroup在dispatchTouchEvent中将事件的坐标转化为相对于子View的坐标再传递给子View的dispatchTouchEvent()
若子View为最小视图单元(即不为ViewpGroup的子类),子View直接将事件传递给onTouchLister()或onTouchEvent。
若onTouchLister()或onTouchEvent返回true则表示消费了事件,
若返回false则传递给上一级视图的onTouchEvnet。
Activity.dispatchTouchEvent()
– Always first to be called
– Sends event to root view attached to Window
– onTouchEvent()
• Called if no view,s consume the event
• Always last to be called
• View.dispatchTouchEvent()
– Sends event to listener first, if exists
• View.OnTouchListener.onTouch()
– If not consumed, processes the touch itself
• View.onTouchEvent()this.setOnTouchListener
ViewGroup.dispatchTouchEvent()
– onInterceptTouchEvent()
• Check if it should supersede children
• Passes ACTION_CANCEL to active child
• Return true once consumes all subsequent events
– For each child view, in reverse order they were added
• If touch is relevant (inside view), child.dispatchTouchEvent()
• If not handled by previous, dispatch to next view
– If no children handle event, listener gets a chance
• OnTouchListener.onTouch()
– If no listener, or not handled
• onTouchEvent()
• Intercepted events jump over child step