1.viewçontoucheventåonintercepttoucheventçåºå«
2.Android Touch事件InputManagerService源码解析(二)
3.UE4-Slate源码学习(二)slate事件触发
4.android onTouchEventåsetOnTouchListenerä¸onTouchçåºå«
5.MotionEventçgetActionãgetActionMaskågetActionIndexçåºå«
viewçontoucheventåonintercepttoucheventçåºå«
onTouchEventï¼è§¦å触æ¸äºä»¶
onInterceptTouchEventï¼è§¦åæ¦æªè§¦æ¸äºä»¶
éè¿æ¥çæºä»£ç å类继æ¿å ³ç³»
onInterceptTouchEvent:æ¯å®ä¹äºViewGroupéé¢çä¸ä¸ªæ¹æ³ï¼æ¤äºä»¶æ¯ç¨äºæ¦æªè§¦æ¸äºä»¶çï¼ViewGroup(继æ¿èªView)ï¼ä¸ä¸ªViewçGroupï¼ä¹å°±æ¯æ们çä¸ä¸ªå¸å±å¦LinerLayoutï¼å个å¸å±ç±»é½ç»§æ¿èªViewGroupï¼
onTouchEvent:æ¯å®ä¹äºViewä¸çä¸ä¸ªæ¹æ³ï¼å¤çä¼ éå°Viewçæå¿è§¦æ¸äºä»¶ãæå¿äºä»¶ç±»åå æ¬ACTION_DOWN,源码ACTION_MOVE,ACTION_UP,ACTION_CANCELçäºä»¶ï¼
å ¶ä¸ViewGroupéçonInterceptTouchEventé»è®¤è¿åå¼æ¯falseï¼è¿æ ·touchäºä»¶ä¼ä¼ éå°Viewæ§ä»¶ï¼ViewGroupéçonTouchEventé»è®¤è¿åå¼æ¯falseï¼
ViewéçonTouchEventé»è®¤è¿åå¼æ¯trueï¼å½æ们ææç¹å»å±å¹æ¶åï¼å è°ç¨ACTION_DOWNäºä»¶ï¼å½onTouchEventéè¿åå¼æ¯trueçæ¶åï¼onTouchä¼ç»§ç»è°ç¨ACTION_UPäºä»¶ï¼å¦æonTouchEventéè¿åå¼æ¯falseï¼é£ä¹onTouchEventåªä¼è°ç¨ACTION_DOWNèä¸è°ç¨ACTION_UPã
Android Touch事件InputManagerService源码解析(二)
解析Android Touch事件分发过程,深入InputManagerService源码。源码触摸事件的源码产生与传递机制是本文探讨的核心。
InputDispatcher接收到事件,源码通过enqueueInboundEventLocked接口将事件放入mInboundQueue队列,源码等待分发处理。源码sscom32 源码
InputDispatcher内部线程在有事件时被唤醒,源码执行dispatchOnce,源码根据事件类型调用dispatchMotionLocked进行处理。源码处理流程涉及找到要处理事件的源码窗口。
窗口查找通过findFocusedWindowTargetsLocked方法实现,源码该方法从map中获取focusedWindowHandle和focusedApplicationHandle,源码存储目标窗口信息。源码
这些句柄的源码初始化在Activity的生命周期回调中,如Activity.onResume时。源码具体路径涉及ActivityTaskManagerService、DisplayContent、InputMonitor和InputManagerService。
分发循环由prepareDispatchCycleLocked、飞猫网盘源码enqueueDispatchEntryLocked和enqueueDispatchEntriesLocked方法实现,最后调用startDispatchCycleLocked,将事件发送给对应进程。
InputReader持续从底层读取事件,InputDispatcher通过线程处理分发,直至事件被发送至目标进程。本文深入解析了Touch事件的分发机制与关键步骤,提供了对Android触摸事件处理过程的全面理解。
UE4-Slate源码学习(二)slate事件触发
在探讨UE4-Slate源码学习中,某站源码泄露首先进入概念理解阶段,虚拟触摸的开启会将鼠标左键操作转化为OnTouchStarted事件,使得编辑器下通过鼠标也能触发UI的触摸相关事件。实现这一功能的关键在于
FSlateApplication类中两个方法:IsFakingTouchEvents()用于判断是否开启虚拟触摸,SetGameIsFakingTouchEvents()用于设置虚拟触摸状态。
在平台调用Slate时,根据不同事件类型创建FPointerEvent对象,作为事件处理的载体,其包含触发事件的在线充值系统源码按键信息、鼠标位置、索引、是否为触摸事件等数据,用于后续事件的精确处理。
Slate用户类FSlateUser包含了索引、鼠标位置、聚焦对象、捕获状态和WidgetPath等信息,通过实例化多个FSlateUser对象,负1010的源码程序可以追踪多个用户输入,例如在多人游戏场景中,能够精准识别当前谁触发了A键。
聚焦和捕获功能分别通过Widget的聚焦和捕获机制实现,当聚焦后,事件将被相应Widget接收,并触发一系列聚焦相关的事件,如OnFocusReceived、OnFocusChanging、OnFocusLost等。以按钮点击为例,点击按钮触发OnMouseDown事件,若按钮被捕获,则移动到按钮外松开鼠标仍会触发按钮的OnMouseUp事件。
在处理输入事件时,会涉及多种策略,如FArrangedWidget、FArrangedChildren和FWidgetPath等,用于确定事件处理的路径和流程。FEventRouter类根据输入事件和用户输入策略(FDirectPolicy、FToLeafmostPolicy、FTunnelPolicy、FBubblePolicy)来组织和分发事件。
处理鼠标和触摸输入的流程分为OnMouseDown和OnTouchStarted,通过Route函数根据策略处理事件,实现事件的触发和响应。移动事件则通过OnMouseMove和OnTouchMoved处理,根据输入类型和用户状态执行相应操作。拖拽事件OnDragDetected则在拖拽开始时触发,允许开发者自定义拖拽行为和数据传递。
最终,事件处理完成后,将调用相关函数清理记录,包括更新用户位置和路径,以及触发OnMouseUp或OnTouchEnded等事件。
UE4-Slate源码的学习涵盖了事件触发、用户输入处理、事件路由策略等多个方面,理解这些机制和流程对于深入掌握Slate框架至关重要。源码版本4..2提供了丰富的功能和细节,为开发者提供了一套强大且灵活的UI管理解决方案。
android onTouchEventåsetOnTouchListenerä¸onTouchçåºå«
触æ¸äºä»¶ååæºå¶ï¼å¥½å¥½ççï¼
/blog/
Androidä¸çäºä»¶å为æé®äºä»¶å触æ¸äºä»¶ï¼è¿é对触æ¸äºä»¶è¿è¡éè¿°ãTouchäºä»¶æ¯ç±ä¸ä¸ªACTION_DOWNï¼n个
ACTION_MOVEï¼ä¸ä¸ªACTION_UPç»æonClickï¼onLongClickï¼onScrollçäºä»¶ãAndroidä¸çæ§ä»¶é½æ¯ç»§æ¿
Viewè¿ä¸ªåºç±»çï¼èæ§ä»¶å为两ç§ï¼ä¸ç§æ¯ç»§æ¿Viewä¸è½å å«å ¶ä»æ§ä»¶çæ§ä»¶ï¼ä¸ç§æ¯ç»§æ¿ViewGroupå¯ä»¥å å«å ¶ä»æ§ä»¶çæ§ä»¶ï¼æä¸ç§°ä¸ºå®¹å¨æ§
件ï¼æ¯å¦ListViewï¼GridViewï¼LinearLayoutçã
è¿éå 对å 个å½æ°è®²è§£ä¸ã
Ø public boolean dispatchTouchEvent (MotionEventev) è¿ä¸ªæ¹æ³ååTouchEvent
Ø public booleanonInterceptTouchEvent(MotionEvent ev) è¿ä¸ªæ¹æ³æ¦æªTouchEvent
Ø public boolean onTouchEvent(MotionEvent ev) è¿ä¸ªæ¹æ³å¤çTouchEvent
å ¶ä¸viewç±»ä¸ædispatchTouchEventåonTouchEvent两个æ¹æ³ï¼ViewGroup继æ¿Viewï¼èä¸è¿æ°æ·»äºä¸ä¸ª
onInterceptTouchEventæ¹æ³ãActivityä¸ä¹æ onInterceptTouchEventæ¹æ³ï¼ä½æå¦å¤ä¸¤ç§æ¹æ³ãæ们å¯ä»¥
åç°ä¸é¢3个æ¹æ³é½æ¯è¿åbooleanï¼é£å代表ä»ä¹ææå¢ï¼
public boolean dispatchTouchEvent (MotionEvent ev)
Activityä¸è§£éï¼
Called to process touch screen
events.You can override this to intercept all touch screen events before
they aredispatched to the window. Be sure to call this implementation
for touch screenevents that should be handled normally.
Parameters
ev
The touch screen event.
Returns
· boolean Return true if this event was consumed.
å®ä¼è¢«è°ç¨å¤ç触æ¸å±äºä»¶ï¼å¯ä»¥éåè¦çæ¤æ¹æ³æ¥æ¦æªææ触æ¸å±äºä»¶å¨è¿äºäºä»¶ååå°çªå£ä¹åãé常åºè¯¥å¤ç触æ¸å±äºä»¶ï¼ä¸å®è¦è°ç¨è¿ä¸ªå®ç°ãå½è¿
åå¼ä¸ºtrueæ¶ï¼è¡¨ç¤ºè¿ä¸ªäºä»¶å·²ç»è¢«æ¶è´¹äºãä¾å¦å¨TextActivityä¸dispatchTouchEventå¨ACTION_MOVEè¿å
trueï¼è¿è¡ç»æå¦ä¸ï¼
ä¹å°±æ¯å®å¹¶æ²¡ææé£ACTION_MOVEååä¸å»ã
public boolean onInterceptTouchEvent (MotionEvent ev)
Implementthis
method to intercept all touch screen motion events. This allows you
towatch events as they are dispatched to your children, and take
ownership of thecurrent gesture at any point.
Usingthis function takes some care, as it has a fairly complicated interaction with View.onTouchEvent(MotionEvent),and
using it requires implementing that method as well as this one in
thecorrect way. Events will be received in the following order:
1. You will receive the down event here.
2. The
down event will be handled either by a child of this viewgroup, or
given to your own onTouchEvent() method to handle; this means youshould
implement onTouchEvent() to return true, so you will continue to see
therest of the gesture (instead of looking for a parent view to handle
it). Also,by returning true from onTouchEvent(), you will not receive
any followingevents in onInterceptTouchEvent() and all touch processing
must happen inonTouchEvent() like normal.
3. For
as long as you return false from this function, eachfollowing event (up
to and including the final up) will be delivered first hereand then to
the target's onTouchEvent().
4. If
you return true from here, you will not receive any followingevents:
the target view will receive the same event but with the action ACTION_CANCEL, and all further events will be delivered to youronTouchEvent() method and no longer appear here.
Parameters
ev
The motion event being dispatched down the hierarchy.
Returns
· Return
true to steal motionevents from the children and have them dispatched
to this ViewGroup throughonTouchEvent(). The current target will receive
an ACTION_CANCEL event, and nofurther messages will be delivered here.
åºæ¬ææå°±æ¯ï¼
1. ACTION_DOWNé¦å ä¼ä¼ éå°onInterceptTouchEvent()æ¹æ³
2.å¦æ该ViewGroupçonInterceptTouchEvent()å¨æ¥æ¶å°downäºä»¶å¤çå®æä¹åreturn falseï¼é£ä¹åç»çmove, upçäºä»¶å°ç»§ç»ä¼å ä¼ éç»è¯¥ViewGroupï¼ä¹åæådownäºä»¶ä¸æ ·ä¼ éç»æç»çç®æ viewçonTouchEvent()å¤çã
3.å¦æ该ViewGroupçonInterceptTouchEvent()å¨æ¥æ¶å°downäºä»¶å¤çå®æä¹åreturn trueï¼é£ä¹åç»çmove, upçäºä»¶å°ä¸åä¼ éç»onInterceptTouchEvent()ï¼èæ¯ådownäºä»¶ä¸æ ·ä¼ éç»è¯¥ViewGroupçonTouchEvent()å¤çï¼æ³¨æï¼ç®æ viewå°æ¥æ¶ä¸å°ä»»ä½äºä»¶ã
4.å¦ææç»éè¦å¤çäºä»¶çviewçonTouchEvent()è¿åäºfalseï¼é£ä¹è¯¥äºä»¶å°è¢«ä¼ éè³å ¶ä¸ä¸å±æ¬¡çviewçonTouchEvent()å¤çã
5.å¦ææç»éè¦å¤çäºä»¶çviewçonTouchEvent()è¿åäºtrueï¼é£ä¹åç»äºä»¶å°å¯ä»¥ç»§ç»ä¼ éç»è¯¥viewçonTouchEvent()å¤çã
Android touchäºä»¶ä¼ éæºå¶ï¼
æ们å¯ä»¥ççandroidæºä»£ç ï¼
Activity.javaä¸
æä¸ä¸ç®¡onUserInteractionæ¹æ³å 为å®åªæ¯ä¸ä¸ªç©ºæ¹æ³å¦æä½ æ²¡å®ç°çè¯ãgetWindow().superDispatchTouchEvent(ev)ãå ¶ä¸getWindow()è¿åçæ¯PhoneWindowã
PhoneWindow.java:
æ¤å½æ°è°ç¨super.dispatchTouchEvent(event),Activityçrootviewæ¯
PhoneWindow.DecorView,å®ç»§æ¿FrameLayoutãéè¿super.dispatchTouchEventætouchäºä»¶æ´¾
åç»å个Activityçæ¯åviewãåæ¶æå¯ä»¥çå°ï¼å¦æåviewæ¦æªäºäºä»¶ï¼åä¸ä¼æ§è¡onTouchEventå½æ°ã
ViewGroup.javaä¸dispatchTouchEventæ¹æ³ï¼
ç±äºä»£ç è¿é¿è¿éå°±ä¸è´´åºæ¥äºï¼ä½ä¹ç¥éå®è¿åçæ¯
return target.dispatchTouchEvent(ev);
è¿étargetæçæ¯æååçç®æ ï¼å¯ä»¥æ¯å®æ¬èº«ï¼ä¹å¯ä»¥æ¯å®çåViewã
ViewGroup.javaä¸çonInterceptTouchEventæ¹æ³ï¼
é»è®¤æ åµä¸è¿åfalseãå³ä¸æ¦æªtouchäºä»¶ã
View.javaä¸çdispatchTouchEventæ¹æ³
è¿éæ们å¾æ¸ æ¥å¯ä»¥ç¥éå¦æifæ¡ä»¶ä¸æç«ådispatchTouchEventçè¿åå¼æ¯onTouchEventçè¿åå¼
View.javaä¸çonTouchEventæ¹æ³
MotionEventçgetActionãgetActionMaskågetActionIndexçåºå«
å¨å¾å¤èªå®ä¹Viewçåºæ¯ä¸ï¼é½æå¯è½éè¦éåonTouchEventãdispatchTouchEventçæ¹æ³ï¼è¿äºæ¹æ³é½ä¼ å ¥ä¸ä¸ªMotionEvent对象ï¼ä¸è¬æ¥è¯´ï¼æ们éè¦éè¿è¯¥MotionEvent对象æ¥è·åå½åçæå¿å¨ä½ï¼ç¶åå¤æAction_DownãAction_MoveãAction_Upæ¥æ§è¡ä¸åçæä½é»è¾ãä½æ¯å½æ们çMotionEvent对象æ¶ï¼åç°å®ægetActionãgetActionMaskågetActionIndexæ¹æ³ï¼èä¸å¨æ们ç第ä¸æ¹æºç æ¶ï¼ç»å¸¸ä¼çå°è¿æ ·çåæ³ï¼
åæ¶ä¹ä¼çå°è¿æ ·çåæ³ï¼
è¿ä¸¤ç§åæ³å°åºæä»ä¹åºå«å¢ï¼æ们就æ¥è¯´ä¸ä¸MotionEventçå ç§è·åActionä¿¡æ¯çæ¹æ³ã
Androidç¨ä¸ä¸ªä½çæ´æ°å¼æ¥è¡¨ç¤ºä¸ä¸ªTouchEventäºä»¶ï¼ä½8ä½è¡¨ç¤ºTouchäºä»¶çå ·ä½å¨ä½ï¼ä¾å¦æä¸ãæ¬èµ·ã移å¨çå¨ä½ãé«8ä½è¡¨ç¤ºTouchäºä»¶ä¸å¤ç¹è§¦æ§çç´¢å¼å¼ã
ä»æºç å¯ä»¥çåºgetActionMasked = getAction & MotionEvent.ACTION_MASK
èMotionEvent.ACTION_MASK æ¯ä¸ä¸ªå¸¸éå¼ï¼å¼ä¸º0xffï¼æ以getActionMaskedæ¹æ³åªä¿çäºä½8ä½çä¿¡æ¯ï¼ä¹å°±æ¯è¯´åªä¿çäºè§¦æ¸çå¨ä½ä¿¡æ¯ã
为ä»ä¹ç第ä¸æ¹æºç æ¶ï¼ææ¶åågetActionï¼ææ¶åågetActionMaskedå¢ï¼ä»ä¸é¢çåæä¸å¯ä»¥çåºæ¥ä¸ªæ以ç¶ï¼
getAction表示触æ¸å¨ä½çåå§ä½ä¿¡æ¯ï¼å½æ²¡æå¤ç¹è§¦æ§æ¶ï¼é«8ä½å³ä¸º0ï¼è¿ä¸ªæ¶ågetAction == getActionMaskedãæ以å½æ们确å®æ们èªå®ä¹çViewä¸ä¼ä½¿ç¨å°å¤ç¹è§¦æ§æ¶ï¼å°±å¯ä»¥ç´æ¥ä½¿ç¨getActionæ¥è¡¨ç¤ºå ·ä½ç触æ¸å¨ä½ãä½å¦æéè¦ä½¿ç¨å¤ç¹è§¦æ§ï¼æè æ¯ä¸ç¡®å®åé¢ä¼ä¸ä¼ä½¿ç¨å¤ç¹è§¦æ§ï¼å使ç¨getActionMaskedåæ¯æä¿é©çæä½ï¼æ以æ们ç»å¸¸çå°ä¸é¢è¿ä¸¤ç§åæ³ï¼
Androidä¸æ¯æ¯æå¤ç¹è§¦æ§çï¼é£ä¹å¨é«8ä½ä¸æ¯å¦ä½åå¨å¤ç¹è§¦æ§çç´¢å¼ä¿¡æ¯çå¢ï¼ä¸¾ä¸ªä¾åæ¥è¯´ï¼
å¦æä»getActionæ¹æ³ä¸è¿åçå¼æ¯0xï¼å表示æ¯ç¬¬ä¸ä¸ªè§¦æ§ç¹çACTION_DOWNæä½ãé«8ä½æ¯0表示第ä¸ä¸ªè§¦æ§ç¹ï¼ä½8ä½æ¯0表示ACTION_DOWNæä½ã
åçï¼å¦æè¿åå¼æ¯0xï¼å表示第äºä¸ªè§¦æ§ç¹çACTION_DOWNæä½ã
ä¹å°±æ¯è¯´ï¼getActionè¿åå¼çä½8ä½è¡¨ç¤ºè§¦æ¸å¨ä½çç±»åä¿¡æ¯ï¼èé«8ä½è¡¨ç¤ºè§¦æ§ç¹çç´¢å¼ä¿¡æ¯ï¼ä¹å°±æ¯åªä¸ä¸ªè§¦æ§ç¹çäºä»¶ã