Android ViewGroup 觸摸屏事件派發機制和源碼分析

分類:編程 時間:2017-02-15

android ViewGroup 觸摸屏事件派發機制和源碼分析

Android 中不管是View 還是ViewGoup,觸摸事件來的時候都是從dispatchTouchEvent開始的.其中dispatchTouchEvent()是View.Java 的方法,ViewGroup 只是重寫了這個方法.ViewGroup的dispatchTouchEvent() 之前最好先看View的dispatchTouchEvent().View 的邏輯簡單些,而且ViewGroup的dispatchTouchEvent()最終也會調用View的dispatchTouchEvent(). 以下分析基於Android L.
我們現在從ViewGroup的dispatchTouchEvent()開始分析.相關代碼如下:
  1. @Override
  2. public boolean dispatchTouchEvent(MotionEvent ev) {
  3. if (mInputEventConsistencyVerifier != null) {
  4. mInputEventConsistencyVerifier.onTouchEvent(ev, 1);
  5. }
  6. // If the event targets the accessibility focused view and this is it, start
  7. // normal event dispatch. Maybe a descendant is what will handle the click.
  8. if (ev.isTargetAccessibilityFocus() && isAccessibilityFocusedViewOrHost()) {
  9. ev.setTargetAccessibilityFocus(false);
  10. }
  11. if (DBG_MOTION || DBG_TOUCH) {
  12. Xlog.d(TAG, "(ViewGroup)dispatchTouchEvent 1: ev = " + ev + ",mFirstTouchTarget = "
  13. + mFirstTouchTarget + ",this = " + this);
  14. }
  15. boolean handled = false;
  16. if (onFilterTouchEventForSecurity(ev)) {//調用View.java判斷當前View 沒有被遮蔽
  17. final int action = ev.getAction();
  18. final int actionMasked = action & MotionEvent.ACTION_MASK;
  19. // Handle an initial down.
  20. if (actionMasked == MotionEvent.ACTION_DOWN) {
  21. // Throw away all previous state when starting a new touch gesture.
  22. // The framework may have dropped the up or cancel event for the previous gesture
  23. // due to an app switch, ANR, or some other state change.
  24. cancelAndClearTouchTargets(ev);
  25. resetTouchState();//mFirstTouchTarget設置為null;mGroupFlags &= ~FLAG_DISALLOW_INTERCEPT;
  26. }
  27. // Check for interception.
  28. final boolean intercepted;
  29. if (actionMasked == MotionEvent.ACTION_DOWN
  30. || mFirstTouchTarget != null) {
  31. final boolean disallowIntercept = (mGroupFlags & FLAG_DISALLOW_INTERCEPT) != 0;//true:不攔截;false:攔截
  32. if (!disallowIntercept) {//攔截
  33. intercepted = onInterceptTouchEvent(ev);// 默認返回false
  34. /// M : add log to help debugging
  35. if (intercepted == true && DBG_TOUCH) {
  36. Xlog.d(TAG, "Touch event was intercepted event = " + ev
  37. + ",this = " + this);
  38. }
  39. ev.setAction(action); // restore action in case it was changed
  40. } else {//不攔截
  41. intercepted = false;
  42. }
  43. } else {
  44. // There are no touch targets and this action is not an initial down
  45. // so this view group continues to intercept touches.
  46. intercepted = true;
  47. }
  48. // If intercepted, start normal event dispatch. Also if there is already
  49. // a view that is handling the gesture, do normal event dispatch.
  50. if (intercepted || mFirstTouchTarget != null) {
  51. ev.setTargetAccessibilityFocus(false);
  52. }
  53. // Check for cancelation.
  54. final boolean canceled = resetCancelNextUpFlag(this)
  55. || actionMasked == MotionEvent.ACTION_CANCEL;//是否cancle事件
  56. // update list of touch targets for pointer down, if needed.
  57. final boolean split = (mGroupFlags & FLAG_SPLIT_MOTION_EVENTS) != 0;//默認true,用於判斷分發事件,作用是判斷可以把事件分發到多個子View.
  58. if (DBG_MOTION) {
  59. Xlog.d(TAG, "(ViewGroup)dispatchTouchEvent 2: actionMasked = " + actionMasked
  60. + ",intercepted = " + intercepted + ",canceled = " + canceled + ",split = "
  61. + split + ",mChildrenCount = " + mChildrenCount + ",mFirstTouchTarget = "
  62. + mFirstTouchTarget + ",this = " + this);
  63. }
  64. TouchTarget newTouchTarget = null;
  65. boolean alreadyDispatchedToNewTouchTarget = false;
  66. if (!canceled && !intercepted) {//沒有被攔截
  67. // If the event is targeting accessiiblity focus we give it to the
  68. // view that has accessibility focus and if it does not handle it
  69. // we clear the flag and dispatch the event to all children as usual.
  70. // We are looking up the accessibility focused host to avoid keeping
  71. // state since these events are very rare.
  72. View childWithAccessibilityFocus = ev.isTargetAccessibilityFocus()
  73. ? findChildWithAccessibilityFocus() : null;
  74. if (actionMasked == MotionEvent.ACTION_DOWN
  75. || (split && actionMasked == MotionEvent.ACTION_POINTER_DOWN)
  76. || actionMasked == MotionEvent.ACTION_HOVER_MOVE) {
  77. final int actionIndex = ev.getActionIndex(); // always 0 for down
  78. final int idBitsToAssign = split ? 1 << ev.getPointerId(actionIndex)
  79. : TouchTarget.ALL_POINTER_IDS;
  80. // Clean up earlier touch targets for this pointer id in case they
  81. // have become out of sync.
  82. removePointersFromTouchTargets(idBitsToAssign);
  83. final int childrenCount = mChildrenCount;
  84. if (newTouchTarget == null && childrenCount != 0) {
  85. final float ads
ads

相關文章
ads

相關文章

ad