代码执行堆栈
@Override public void handleMessage(Message msg) { ...... case DISPATCH_POINTER: deliverPointerEvent((MotionEvent) msg.obj, msg.arg1 != 0); ...... }
private void deliverPointerEvent(MotionEvent event, boolean sendDone) { if (ViewDebug.DEBUG_LATENCY) { mInputEventDeliverTimeNanos = System.nanoTime(); } final boolean isTouchEvent = event.isTouchEvent(); if (mInputEventConsistencyVerifier != null) { if (isTouchEvent) { mInputEventConsistencyVerifier.onTouchEvent(event, 0); } else { mInputEventConsistencyVerifier.onGenericMotionEvent(event, 0); } } // If there is no view, then the event will not be handled. if (mView == null || !mAdded) { finishMotionEvent(event, sendDone, false); return; } // Translate the pointer event for compatibility, if needed. if (mTranslator != null) { mTranslator.translateEventInScreenToAppWindow(event); } // Enter touch mode on down or scroll. final int action = event.getAction(); if (action == MotionEvent.ACTION_DOWN || action == MotionEvent.ACTION_SCROLL) { ensureTouchMode(true); } // Offset the scroll position. if (mCurScrollY != 0) { event.offsetLocation(0, mCurScrollY); } if (MEASURE_LATENCY) { lt.sample("A Dispatching PointerEvents", System.nanoTime() - event.getEventTimeNano()); } // Remember the touch position for possible drag-initiation. if (isTouchEvent) { mLastTouchPoint.x = event.getRawX(); mLastTouchPoint.y = event.getRawY(); } // Dispatch touch to view hierarchy. // 派发Touch Event boolean handled = mView.dispatchPointerEvent(event); if (MEASURE_LATENCY) { lt.sample("B Dispatched PointerEvents ", System.nanoTime() - event.getEventTimeNano()); } if (handled) { finishMotionEvent(event, sendDone, true); return; } // Pointer event was unhandled. finishMotionEvent(event, sendDone, false); }
@Override public boolean dispatchTouchEvent(MotionEvent ev) { final Callback cb = getCallback(); // cb != null cb就是拥有这个PhoneWindow的Activity // return cb != null && !isDestroyed() && mFeatureId < 0 ? cb.dispatchTouchEvent(ev) : super.dispatchTouchEvent(ev); }
/** * Called to process touch screen events. You can override this to * intercept all touch screen events before they are dispatched to the * window. Be sure to call this implementation for touch screen events * that should be handled normally. * * @param ev The touch screen event. * * @return boolean Return true if this event was consumed. */ public boolean dispatchTouchEvent(MotionEvent ev) { if (ev.getAction() == MotionEvent.ACTION_DOWN) { onUserInteraction(); } if (getWindow().superDispatchTouchEvent(ev)) { return true; } return onTouchEvent(ev); }
@Override public boolean superDispatchTouchEvent(MotionEvent event) { return mDecor.superDispatchTouchEvent(event); }
public boolean superDispatchTouchEvent(MotionEvent event) { return super.dispatchTouchEvent(event); }
/** * Called when a touch screen event was not handled by any of the views * under it. This is most useful to process touch events that happen * outside of your window bounds, where there is no view to receive it. * * @param event The touch screen event being processed. * * @return Return true if you have consumed the event, false if you haven't. * The default implementation always returns false. */ public boolean onTouchEvent(MotionEvent event) { if (mWindow.shouldCloseOnTouch(this, event)) { finish(); return true; } return false; }