【push源码】【买卖潮指标源码】【2023新款源码】触摸源码_触控代码

时间:2024-12-24 02:59:51 编辑:掌上植入系统源码 来源:员工商城源码

1.MotionEvent的getAction、getActionMask和getActionIndex的区别
2.Android Touch事件InputManagerService源码解析(二)
3.UE4-Slate源码学习(四)FSceneViewport
4.android onTouchEvent和setOnTouchListener中onTouch的区别
5.linux内核hid触摸源码hid-multitouch.c剖析
6.UE4-Slate源码学习(二)slate事件触发

触摸源码_触控代码

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位表示触控点的索引信息,也就是哪一个触控点的事件。

Android Touch事件InputManagerService源码解析(二)

       解析Android Touch事件分发过程,触摸触控深入InputManagerService源码。源码触摸事件的代码产生与传递机制是本文探讨的核心。

       InputDispatcher接收到事件,触摸触控通过enqueueInboundEventLocked接口将事件放入mInboundQueue队列,源码等待分发处理。代码push源码

       InputDispatcher内部线程在有事件时被唤醒,触摸触控执行dispatchOnce,源码根据事件类型调用dispatchMotionLocked进行处理。代码处理流程涉及找到要处理事件的触摸触控窗口。

       窗口查找通过findFocusedWindowTargetsLocked方法实现,源码该方法从map中获取focusedWindowHandle和focusedApplicationHandle,代码存储目标窗口信息。触摸触控

       这些句柄的源码初始化在Activity的生命周期回调中,如Activity.onResume时。代码具体路径涉及ActivityTaskManagerService、DisplayContent、买卖潮指标源码InputMonitor和InputManagerService。

       分发循环由prepareDispatchCycleLocked、enqueueDispatchEntryLocked和enqueueDispatchEntriesLocked方法实现,最后调用startDispatchCycleLocked,将事件发送给对应进程。

       InputReader持续从底层读取事件,InputDispatcher通过线程处理分发,直至事件被发送至目标进程。本文深入解析了Touch事件的分发机制与关键步骤,提供了对Android触摸事件处理过程的全面理解。

UE4-Slate源码学习(四)FSceneViewport

       即视口是引擎中显示游戏画面的SWidget控件,也是编辑器中显示游戏内容的窗口。场景绘制视口(FSceneViewport)与SViewport绑定,用于场景渲染。鼠标捕获模式(EMouseCaptureMode)与鼠标锁定模式(EMouseLockMode)在项目设置中可配置,影响鼠标的2023新款源码交互。FSceneViewport事件处理包括鼠标按下(OnMouseButtonDown)、触摸开始(OnTouchStarted),事件响应后构造FReply,并更新几何体缓存、鼠标位置缓存。鼠标位置由绝对坐标转换为相对于视口的相对坐标。根据捕获状态和输入处理逻辑,事件最终被传递至PlayerController,通过PlayerInput管理。对于触摸输入,处理流程类似,调用InputTouch接口。

       移动事件(OnMouseMove)、触摸移动(OnTouchMoved)记录鼠标的Delta和NumMouseSample累计值,Tick时处理。ProcessAccumulatedPointerInput在Tick阶段调用,洗地毯游戏源码处理键盘、鼠标输入,相关流程见第二章。完成输入处理后,FEngineLoop调用FinishedInputThisFrame,最终在ProcessAccumulatedPointerInput中调用InputAxis,处理至PlayerController的InputAxis,存储在PlayerInput中。其他事件如鼠标释放(OnMouseButtonUp)、触摸结束(OnTouchEnded)同样遵循类似流程。

       若SWidget为视口,执行相关事件调用至ViewportClient接口,进而触发输入系统(PlayerController、PlayerInput、InputComponent)。日常游戏开发中,高山线源码通过视口事件实现如旋转相机、隐藏鼠标等操作。PlayerController提供三种模式(FInputModeUIOnly、FInputModeGameAndUI、FInputModeGameOnly),通过调整SViewport和ViewportClient参数,实现不同模式下的捕获、锁定、显隐鼠标功能。所讨论内容基于UE4版本4..2。

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方法

linux内核hid触摸源码hid-multitouch.c剖析

       在Linux内核中,hid-multitouch.c文件负责实现通用的HID触摸驱动。驱动结构定义在mt_driver中,通过module_hdi_driver()函数构建模块。mt_devices数组定义了设备参数,遵循USB-HID协议,通过HID_DEVICE宏对各个字段赋值。

       mt_probe()函数执行初始化和配置多点触摸设备的操作,根据设备特性设置属性,启动硬件,并创建sysfs属性组。hid_parse()函数调用hid_open_report()解析HID报告,通过遍历数据并调用特定函数解析。hid_hw_start()函数启动底层HID硬件,而hid_connect()函数则实现连接功能。

       对于需要通过USB接入触摸面板且满足HID协议的场景,可以使用hid-multitouch.c。接上两块触摸面板后,内核生成对应的设备节点链接。验证结果显示,内核能够正常解析触摸面板的数据,触摸事件上报亦正常。

UE4-Slate源码学习(二)slate事件触发

       在探讨UE4-Slate源码学习中,首先进入概念理解阶段,虚拟触摸的开启会将鼠标左键操作转化为OnTouchStarted事件,使得编辑器下通过鼠标也能触发UI的触摸相关事件。实现这一功能的关键在于

       FSlateApplication类中两个方法:IsFakingTouchEvents()用于判断是否开启虚拟触摸,SetGameIsFakingTouchEvents()用于设置虚拟触摸状态。

       在平台调用Slate时,根据不同事件类型创建FPointerEvent对象,作为事件处理的载体,其包含触发事件的按键信息、鼠标位置、索引、是否为触摸事件等数据,用于后续事件的精确处理。

       Slate用户类FSlateUser包含了索引、鼠标位置、聚焦对象、捕获状态和WidgetPath等信息,通过实例化多个FSlateUser对象,程序可以追踪多个用户输入,例如在多人游戏场景中,能够精准识别当前谁触发了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管理解决方案。