网站建设所需要的技术搜索广告是什么意思
Android事件源码分析:
Android事件传递(一):Activity、View、ViewGroup及dispatchtouchEvent、onTouchEvent梳理
Android事件传递(二):事件动作 DOWN 在Activity、View、ViewGroup传递
Android事件传递(三):事件动作 UP 在Activity、View、ViewGroup传递
Android事件传递(四):总结篇
偶尔看到一个问答:https://ask.csdn.net/questions/246798,为什么onTouchEvent方法会在dispatchTouchEvent方法之前执行呢?就跟了一下源码重新看了一下Android的事件传递流程
回答如下:
public class MyButton extends Button {。。。。。省略代码。。。。。。@Overridepublic boolean dispatchTouchEvent(MotionEvent event) {switch (event.getAction()) {case MotionEvent.ACTION_DOWN:Log.d("TTTT", "context:" + mContext + "MyButton|dispatchTouchEvent|return:" + super.dispatchTouchEvent(event) + "|event:DOWN");break;case MotionEvent.ACTION_MOVE:Log.d("TTTT", "context:" + mContext + "MyButton|dispatchTouchEvent|return:" + super.dispatchTouchEvent(event) + "|event:MOVE");break;case MotionEvent.ACTION_UP:Log.d("TTTT", "context:" + mContext + "MyButton|dispatchTouchEvent|return:" + super.dispatchTouchEvent(event) + "|event:UP");break;}Log.d("TTTT", "========================== ");return super.dispatchTouchEvent(event);}。。。。。省略代码。。。。。。
}
onTouchEvent方法会在dispatchTouchEvent方法之前执行是因为你在打印日志的时候调用了super.super.dispatchTouchEvent(event)
即在DOWN和UP打印日志的代码:
Log.d("TTTT", "context:" + mContext + "MyButton|dispatchTouchEvent|return:" + super.dispatchTouchEvent(event) + "|event:DOWN");Log.d("TTTT", "context:" + mContext + "MyButton|dispatchTouchEvent|return:" + super.dispatchTouchEvent(event) + "|event:UP");
这时候会调用MyButton的父类View的dispatchTouchEvent方法
public boolean dispatchTouchEvent(MotionEvent event) {// If the event should be handled by accessibility focus first.if (event.isTargetAccessibilityFocus()) {// We don't have focus or no virtual descendant has it, do not handle the event.if (!isAccessibilityFocusedViewOrHost()) {return false;}// We have focus and got the event, then use normal event dispatch.event.setTargetAccessibilityFocus(false);}boolean result = false;if (mInputEventConsistencyVerifier != null) {mInputEventConsistencyVerifier.onTouchEvent(event, 0);}final int actionMasked = event.getActionMasked();if (actionMasked == MotionEvent.ACTION_DOWN) {// Defensive cleanup for new gesturestopNestedScroll();}if (onFilterTouchEventForSecurity(event)) {if ((mViewFlags & ENABLED_MASK) == ENABLED && handleScrollBarDragging(event)) {result = true;}//noinspection SimplifiableIfStatementListenerInfo 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;}}if (!result && mInputEventConsistencyVerifier != null) {mInputEventConsistencyVerifier.onUnhandledEvent(event, 0);}// Clean up after nested scrolls if this is the end of a gesture;// also cancel it if we tried an ACTION_DOWN but we didn't want the rest// of the gesture.if (actionMasked == MotionEvent.ACTION_UP ||actionMasked == MotionEvent.ACTION_CANCEL ||(actionMasked == MotionEvent.ACTION_DOWN && !result)) {stopNestedScroll();}return result;}
这个时候就调用了MyButton的onTouchEvent方法会先打印 onTouchEvent的日志
然后再打印 dispatchTouchEvent 日志,在MyButton#dispatchTouchEvent 最后又return super.dispatchTouchEvent(event);
这时又会调用MyButton的onTouchEvent再打印一次 onTouchEvent的日志
最终得日志就变成了
03-31 11:51:08.493: D/TTTT(1609): context:com.example.testtouchevent.MainActivity@528486ecMyButton|onTouchEvent|return:true|event:DOWN
03-31 11:51:08.493: D/TTTT(1609): context:com.example.testtouchevent.MainActivity@528486ecMyButton|dispatchTouchEvent|return:true|event:DOWN
03-31 11:51:08.493: D/TTTT(1609): ==========================
03-31 11:51:08.493: D/TTTT(1609): context:com.example.testtouchevent.MainActivity@528486ecMyButton|onTouchEvent|return:true|event:DOWN