#å®åç³»ç»ç¹å»äºä»¶å¤ç [åèPPT](http://devsbuild.it/content/Mastering-Android-Touch-System) ##å®åç³»ç»ç¹å»äºä»¶å¤çæ¡æ¶ + ç¨æ·çç¹å»äºä»¶å被å è£ ä¸ºMotionEvent + MotionEventæè¿°äºç¨æ·çè¡ä¸º + ACTION_DOWN + ACTION_UP + ACTION_MOVE + ACTION_POINTER_DOWN + ACTION_POINTER_UP + ACTION_CANCEL + MotionEventè¿å æ¬ä»¥ä¸ä¿¡æ¯ + ç¹å»çä½ç½®ï¼x, yåæ ï¼ + 触ç¹çæ°éï¼ææï¼ + äºä»¶åççæ¶é´æ³ + ä»»ä½ä¸ä¸ªæå¿ï¼é½æ¯ä»¥ACTION_DOWNèµ·å§ï¼ACTION_UPç»æ + äºä»¶ä»ActivityçdispatchTouchEvent()彿°å¼å§ï¼æ²¿çView屿¬¡æ 便¬¡åä¸ä¼ é + ç¶å ç´ æäºä»¶dispatchå°åå ç´ + äºä»¶è½å¨ä»»æé¶æ®µè¢«intercept + äºä»¶ä¼æ²¿çView屿¬¡æ 便¬¡åä¸ä¼ éï¼ç¶åååååä¸ä¼ éï¼ç¥éè¢«âæ¶è´¹â + View妿坹æå¿æå ´è¶£ï¼å°±å¿ é¡»æ¶è´¹æACTION_DOWNçäºä»¶ + åºäºæ§è½çèèï¼å䏿å¿çåç»äºä»¶å°ä¸ä¼æç §å®æ´è·¯å¾è¿è¡ä¼ éï¼èæ¯ç´æ¥ä¼ éå°æ¶è´¹äºACTION_DOWNäºä»¶çView + 妿ææçView(ViewGroup)齿²¡ææ¶è´¹æäºä»¶ï¼é£å®å°ä¼ éå°ActivityçonTouchEvent()彿°ä¸ï¼å¹¶ç»æä¼ éè¿ç¨ï¼å³å¦ææ²¡æè¢«æ¶è´¹ï¼ä¹ä¸ä¼åç»§ç»ä¼ éäº + å¯éçOnTouchListenerè½å¨ä»»ä¸View(ViewGroup)ä¸interceptäºä»¶ï¼äºä»¶è¢«interceptä¹åï¼åé¢çè°ç¨å°è¢«ä¼ å ¥ACTION_CANCEL + `Activity.dispatchTouchEvent()` + æ»æ¯é¦å 被è°ç¨ + Sends event to root view attached to Window + 妿ææçView(ViewGroup)齿²¡ææ¶è´¹è¯¥äºä»¶ï¼é£ä¹`Activity.onTouchEvent()`å°è¢«è°ç¨ï¼èä¸è¿ä¸ªå½æ°æ¯æåä¸ä¸ªè¢«è°ç¨ç彿° + `ViewGroup.dispatchTouchEvent()` + é¦å è°ç¨`onInterceptTouchEvent()`彿°ï¼è¿è¡è¿æ»¤å¤ç + æ£æ¥æ¯å¦åºè¯¥æ¿ä»£å©åçå¤ç + Passes ACTION_CANCEL to active child + å¦æè¦æ¶è´¹æå䏿å¿çææåç»äºä»¶ï¼å°è¿åtrue + 对ææçå©åï¼ä»¥æ·»å 顺åºçéåºè¿è¡éå + 妿ç¹å»å¨å©åçè¾¹çå ï¼åè°ç¨`child.dispatchTouchEvent()` + å¦ææ²¡æè¢«å½åçå©åæ¶è´¹ï¼åä¼ éå°ä¸ä¸ä¸ªå©å + 妿ææçå©å齿ªæ¶è´¹è¯¥äºä»¶ï¼åä¼ éç»listenerï¼`OnTouchListener.onTouch()` + å¦ææ²¡ælistenerï¼æè listener乿ªæ¶è´¹ï¼åèªå·±å¤çï¼è°ç¨`ViewGroup.onTouchEvent()` + Intercepted events jump over child step + `View.dispatchTouchEvent()` + å¦æè¢«è®¾ç½®äºOnTouchListenerï¼é£ä¹å°å æäºä»¶åéå°listenerï¼è°ç¨`View.OnTouchListener.onTouch()` + 妿listeneræ²¡ææ¶è´¹äºä»¶ï¼å°è°ç¨`View.onTouchEvent()`ï¼å³èªå·±å¤çç¹å»äºä»¶ + ä¾å + View对äºä»¶ä¸æå ´è¶£  + View对äºä»¶æå ´è¶£  + äºä»¶è¢«ViewGroup intercept  + å°ç» + æå¿ä»¥ACTION_DOWNèµ·å§ï¼ä»¥ACTION_UPç»æ + ACTION_DOWNï¼å¨æ¯ä¸å±Viewä¸é½ä¼è°ç¨`dispatchTouchEvent()`ï¼è¯¥Viewä¼å¤ææ¯å¦å¯¹æ¥ä¸æ¥çæå¿æå ´è¶£ï¼åç»çç¹å»äºä»¶å°ç´æ¥ä¼ éå°æå ´è¶£çView + ViewGroupå¯ä»¥interceptä¸ä¸ªæå¿ï¼å 为`onInterceptTouchEvent()`æ¯å¨`dispatchTouchEvent()`彿°ä¸æå 被è°ç¨çï¼å¦æ`onInterceptTouchEvent()`è¿åtrueï¼å®çå©åå°ä¸ä¼æ¶å°è¯¥æå¿çåç»äºä»¶ ##èªå®ä¹ç¹å»äºä»¶å¤ç + éå¾ + ï¼View/ViewGroupåç±»ï¼Targetï¼éè½½`onTouchEvent()`彿° + 为Target设置`OnTouchListener` + æ¶è´¹äºä»¶ï¼`onTouchEvent()`ï¼ + ACTION_DOWNï¼å¦æå¯¹æå¿æå ´è¶£ï¼é£ä¹ACTION_DOWNçeventå°±è¦è¿åtrueï¼å³ä¾¿å¯¹äºACTION_DOWNä¸æå ´è¶£ + åç»çäºä»¶ï¼åæ ·è¿åtrueï¼ç»æäºä»¶çå¤çæµç¨ + ViewConfigurationçä¸äºæç¨æ¹æ³ + `getScaledTouchSlop()`ï¼å¤æä¸ä¸ªç§»å¨è·ç¦»æ¯å¦ä¸ºdrag + `getScaledMinimumFlingVelocity()`ï¼å¤æä¸ä¸ªææ½é度æ¯å¦ä¸ºfling + `getLongPressTimeout()`ï¼å¤æä¸ä¸ªtouchæ¶é´æ®µæ¯å¦ä¸ºlong press + ä¼ éç¹å»äºä»¶ è°ç¨targetç`dispatchTouchEvent()`ï¼ä¸è¦ç´æ¥è°ç¨targetç`onTouchEvent()` + ViewGroupæ¦æªç¹å»äºä»¶ + éè½½`onInterceptTouchEvent()` + 妿坹å½åçæå¿æå ´è¶£ï¼`onInterceptTouchEvent()`è¿åtrueï¼ä¹åçç¹å»äºä»¶å°ä¸åç»è¿`onInterceptTouchEvent()`彿° + å ¶ä»çtargetï¼ä¹åæ¶è´¹äºä»¶çView/ViewGroupï¼å°æ¶å°ACTION_CANCEL + ä¸äºå»ºè®®/è¦å + å°½éè°ç¨superçå¯¹åºæ¹æ³ï¼ç¶ç±»ä¸å·²ç»åäºå¾å¤åºç¡å·¥ä½äº + ACTION_MOVEçå¤çä¸ï¼æ£æ¥ç§»å¨è·ç¦»æ¯å¦è¶ è¿slopï¼`getScaledTouchSlop()`ï¼ + å¤çACTION_CANCELäºä»¶ï¼ç¶Viewå¯è½ä¼æ¦æªäºä»¶ï¼ACTION_CANCELåéè¦éç½®ç¶æï¼ä¸ä¹å该æå¿å°ä¸ä¼åæ¶å°ä»»ä½äºä»¶ + interceptä¹åï¼è¯¥æå¿ä¹åçææäºä»¶é½å°è¢«æ¦æªï¼æä»¥ä¸è¦è½»ææ¦æª + å¤è§¦ç¹äºä»¶ååº + `MotionEvent.getPointerCount()`ï¼è·åå½åå±å¹ä¸çè§¦ç¹æ°é + ACTION_POINTER_DOWNï¼ACTION_POINTER_UPç¨æ¥ååºæ¬¡è§¦ç¹çäºä»¶ï¼`MotionEvent.getActionMasked()`ï¼`MotionEvent.getActionIndex()` + MotionEventçæäºæ¹æ³ä¼æä¸¤ä¸ªçæ¬ï¼å¸¦indexåæ°çï¼ç¨äºè·å第index个触ç¹çæ°æ®ï¼ä¸å¸¦åæ°çï¼è·å主触ç¹ï¼ç¬¬ä¸ä¸ªè§¦ç¹ï¼çæ°æ® + æ¹éå¤ç + åºäºæççèèï¼ACTION_MOVEå¯ä»¥è¢«æå å°ä¸ä¸ªMotionEventè¿è¡å¤ç + æè¿ä¸æ¬¡ï¼æ¬æ¬¡ï¼äºä»¶çä¿¡æ¯ï¼éè¿æ åçæ¹æ³è·åï¼`getX()`, `getY()`, `getEventTime()` + æ¬æ¬¡åææ©ä¸æ¬¡ACTION_MOVEçä¿¡æ¯ï¼éè¿ç¸åºhistoricalçæ¹æ³è·å + `getHistorySize()`è·åæå çæ°é + `getHistorical*(pos)`è·å第ä¸ä¸ªè§¦ç¹ç第pos个åå²äºä»¶çä¿¡æ¯ + `getHistorical*(index, pos)`è·å第index个触ç¹ç第pos个åå²äºä»¶çä¿¡æ¯ + Can reconstruct all events as they occurred in time for maximum precision + System Touch Handlers + ä¸è¦é¦å å°±èè使ç¨èªå®ä¹çäºä»¶å¤çæ¹å¼ + `OnClickListener` + `OnLongClickListener` + `OnTouchListener` + ç嬿¯ä¸ä¸ªMotionEventï¼èä¸éè¦ç¼ååç±» + å¯ä»¥å¨Listener䏿¶è´¹äºä»¶ + ViewçonTouchEventå¤çä¸ï¼ä¼å è°ç¨çæ¯listenerçå¤ç彿° + `OnScrollListener` / `View.onScrollChanged()` + `GestureDetector` + onDown(), onSingleTapUp(), onDoubleTap() + onLongPress() + onScroll() (userdraggingfinger) + onFling() (userreleaseddragwithvelocity) + `ScaleGestureDetector` + onScaleBegin(),onScale(),onScaleEnd() + Handled via OnTouchListener or onTouchEvent() + Disadvantages + Consume UP events and exposes no interface for CANCEL events + May require added touch handling if these cases need special handling (e.g. reset a View's appearance) + Touch Delegate + Specialized object to assist in forwarding touches from a parent view to its child + Allows for the touch area of a specific view to be different than its actual bounds + Called in onTouchEvent() of attached Viewï¼Events have to make it that far without being consumed by a child or listenerï¼ + TouchDelegate is designed to be set on the PARENT and passed the CHILD view that touches should be forwarded to ```java ViewGroup parent; View child; Rect touchArea; parent.setTouchDelegate(new TouchDelegate(touchArea, child)); ```