scrcpy学习--多点触控事件的模拟

 

input tap x y 命令可以进行模拟点击,但是只是一个点的事件,怎么进行多点模拟操作呢?

其实在MotionEvent里面把多点信息写进去就可以了。

 

我们可以参考scrcpy里面的写法,

https://github.com/Genymobile/scrcpy

 

    private boolean injectTouch(int action, long pointerId, Position position, float pressure, int buttons) {

        long now = SystemClock.uptimeMillis();

 

        Point point = device.getPhysicalPoint(position);

        if (point == null) {

            // ignore event

            return false;

        }

 

        int pointerIndex = pointersState.getPointerIndex(pointerId);

        if (pointerIndex == -1) {

            Ln.w("Too many pointers for touch event");

            return false;

        }

// pointersState里对pointer进行添加等管理

        Pointer pointer = pointersState.get(pointerIndex);

        pointer.setPoint(point);

        pointer.setPressure(pressure);

        pointer.setUp(action == MotionEvent.ACTION_UP);

//这里设置pointerProperties, pointerCoords

        int pointerCount = pointersState.update(pointerProperties, pointerCoords);

 

        if (pointerCount == 1) {

            if (action == MotionEvent.ACTION_DOWN) {

                lastTouchDown = now;

            }

        } else {

//设置多点事件的action,如105,105,205

            // secondary pointers must use ACTION_POINTER_* ORed with the pointerIndex

            if (action == MotionEvent.ACTION_UP) {

                action = MotionEvent.ACTION_POINTER_UP | (pointerIndex << MotionEvent.ACTION_POINTER_INDEX_SHIFT);

            } else if (action == MotionEvent.ACTION_DOWN) {

                action = MotionEvent.ACTION_POINTER_DOWN | (pointerIndex << MotionEvent.ACTION_POINTER_INDEX_SHIFT);

            }

        }

 

        MotionEvent event = MotionEvent

                .obtain(lastTouchDown, now, action, pointerCount, pointerProperties, pointerCoords, 0, buttons, 1f, 1f, DEVICE_ID_VIRTUAL, 0,

                        InputDevice.SOURCE_TOUCHSCREEN, 0);

        return device.injectEvent(event);

}

 

 

调用injectInputEvent方法

 

    public boolean injectEvent(InputEvent event) {

        return injectEvent(event, InputManager.INJECT_INPUT_EVENT_MODE_ASYNC);

    }

 

    public boolean injectEvent(InputEvent inputEvent, int mode) {

        if (!supportsInputEvents()) {

            throw new AssertionError("Could not inject input event if !supportsInputEvents()");

        }

 

        if (displayId != 0 && !InputManager.setDisplayId(inputEvent, displayId)) {

            return false;

        }

 

        return serviceManager.getInputManager().injectInputEvent(inputEvent, mode);

    }

 

 

设置好几个点的轨迹,组装好MotionEvent, 就可以使用injectInputEvent来注入多点触控事件了。MotionEvent的getActionIndex方法可以获取到当前的操作的事件是哪个点发起的。

 

MotionEvent的log

 

03-14 14:03:41.892 28564 28564 D test614 : MotionEvent { action=ACTION_MOVE, act

ionButton=0, id[0]=0, x[0]=357.66882, y[0]=888.5372, toolType[0]=TOOL_TYPE_FINGE

R, id[1]=1, x[1]=866.198, y[1]=1360.2915, toolType[1]=TOOL_TYPE_FINGER, buttonSt

ate=0, metaState=0, flags=0x0, edgeFlags=0x0, pointerCount=2, historySize=0, eve

ntTime=689571391, downTime=689567853, deviceId=8, source=0x1002 }

03-14 14:03:41.909 28564 28564 D test614 : MotionEvent { action=ACTION_MOVE, act

ionButton=0, id[0]=0, x[0]=348.67715, y[0]=894.53406, toolType[0]=TOOL_TYPE_FING

ER, id[1]=1, x[1]=866.198, y[1]=1361.7908, toolType[1]=TOOL_TYPE_FINGER, buttonS

tate=0, metaState=0, flags=0x0, edgeFlags=0x0, pointerCount=2, historySize=1, ev

entTime=689571407, downTime=689567853, deviceId=8, source=0x1002 }

03-14 14:03:41.944 28564 28564 D test614 : MotionEvent { action=ACTION_MOVE, act

ionButton=0, id[0]=0, x[0]=348.67715, y[0]=894.53406, toolType[0]=TOOL_TYPE_FING

ER, id[1]=1, x[1]=865.1989, y[1]=1362.1178, toolType[1]=TOOL_TYPE_FINGER, button

State=0, metaState=0, flags=0x0, edgeFlags=0x0, pointerCount=2, historySize=1, e

ventTime=689571445, downTime=689567853, deviceId=8, source=0x1002 }

03-14 14:03:41.961 28564 28564 D test614 : MotionEvent { action=ACTION_MOVE, act

ionButton=0, id[0]=0, x[0]=348.67715, y[0]=894.53406, toolType[0]=TOOL_TYPE_FING

ER, id[1]=1, x[1]=865.1989, y[1]=1362.79, toolType[1]=TOOL_TYPE_FINGER, buttonSt

ate=0, metaState=0, flags=0x0, edgeFlags=0x0, pointerCount=2, historySize=1, eve

ntTime=689571453, downTime=689567853, deviceId=8, source=0x1002 }

 

连接蓝牙鼠标的点击log

03-14 22:23:51.896 28564 28564 D test614 : MotionEvent { action=ACTION_DOWN, act

ionButton=0, id[0]=0, x[0]=270.19272, y[0]=632.4363, toolType[0]=TOOL_TYPE_MOUSE

, buttonState=BUTTON_PRIMARY, metaState=0, flags=0x0, edgeFlags=0x0, pointerCoun

t=1, historySize=0, eventTime=719579827, downTime=719579827, deviceId=16, source

=0x2002 }

03-14 22:23:52.052 28564 28564 D test614 : MotionEvent { action=ACTION_UP, actio

nButton=0, id[0]=0, x[0]=270.19272, y[0]=632.4363, toolType[0]=TOOL_TYPE_MOUSE,

buttonState=0, metaState=0, flags=0x0, edgeFlags=0x0, pointerCount=1, historySiz

e=0, eventTime=719579984, downTime=719579827, deviceId=16, source=0x2002 }

 

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: WinForms是微软的一个桌面应用程序开发框架,用于创建Windows操作系统上的图形用户界面。然而,WinForms在多点触控方面的功能相对较弱。 要支持WinForms中的多点触控,我们可以使用.NET框架中的一些技术和类库。首先,我们需要将应用程序的TargetFramework设置为.NET Framework 4.6或更高版本,以便能够使用最新的触控功能。 在WinForms中,我们可以使用Control类中的一些事件和属性来处理多点触控。例如,我们可以使用Control类中的MouseEnter、MouseMove和MouseLeave事件来追踪触摸设备的位置和动作。另外,我们还可以使用Control类中的Handle属性来获取控件的句柄,以便与Windows操作系统的触控事件进行交互。 此外,我们还可以使用.NET Framework中的WPF(Windows Presentation Foundation)来实现更高级的多点触控功能。WPF是一个用于创建富客户端应用程序的框架,它提供了更强大和灵活的触控支持。在WPF中,我们可以使用Touch类和触摸事件来处理多点触控。 总的来说,WinForms对于多点触控的支持相对较弱,但是我们可以通过使用.NET Framework中的一些技术和类库来实现一些基本的多点触控功能。如果需要更高级的多点触控功能,则建议使用WPF来开发应用程序。 ### 回答2: Winform是微软Windows操作系统下的一种图形用户界面应用程序的开发框架,用于构建Windows桌面应用程序。然而,Winform并不原生支持多点触控。 要实现Winform多点触控功能,可以借助第三方库或手动实现。其中一种方法是使用Microsoft Surface SDK或TouchToolkit,它们提供了一些用于处理触控输入的类和控件,可以实现多点触控的支持。这些库通常提供了手势识别、滑动、旋转和缩放等常见的多点触控操作功能。 另一种方法是通过手动捕获和处理原始的触控输入信息。可以在Winform应用程序中重写WndProc方法,并使用Windows消息机制来处理WM_TOUCH消息,从而获取触控输入的信息。然后,可以使用这些信息来实现自定义的多点触控交互逻辑。 无论使用哪种方法,都需要在程序中实现对触控事件的处理逻辑。可以通过在触控事件处理程序中使用适当的代码来响应不同的触控手势,例如单击、双击、长按、滑动等。同时,还可以根据需要对控件进行布局调整,以适应不同的屏幕尺寸和触控操作。 需要注意的是,Winform作为一种传统的桌面应用程序开发框架,其多点触控的支持相对较弱。如果需要更丰富的多点触控功能,推荐考虑使用更为现代的UI开发框架,如WPF或UWP。这些框架提供了更为强大和易用的多点触控支持,可以满足更复杂的用户交互需求。 ### 回答3: WinForms是一种用于开发Windows桌面应用程序的框架,它提供了一系列的UI控件和功能,用于创建丰富的用户界面。然而,WinForms并没有直接支持多点触控的能力,因为它是在较早的时期开发的,当时多点触控并不是主流。 要在WinForms应用程序中实现多点触控,我们可以借助一些第三方库或基于WinForms的扩展来实现。这些库或扩展通常提供了额外的控件和事件来处理多点触控操作。 一种常见的方法是使用TouchHook库来捕获触摸事件。TouchHook是一个高级触摸输入库,它实现了自定义的触摸事件处理逻辑。通过使用TouchHook,我们可以在WinForms应用程序中捕获并处理各种触摸手势,例如滑动、缩放、旋转等。 另一种方法是使用基于WinForms的扩展库,如TeeChart.NET。TeeChart.NET提供了一系列的触摸友好的图表控件,可以通过手势实现图表的交互操作。使用TeeChart.NET,我们可以轻松地在WinForms应用程序中实现触摸导航、缩放和平移等功能。 除了使用第三方库和扩展,我们还可以通过自定义绘制和事件处理来实现基本的多点触控功能。通过捕获鼠标事件和触摸事件,我们可以确定触摸点的位置和操作,并相应地更新UI。 总结来说,虽然WinForms本身并没有原生支持多点触控,但我们可以通过使用第三方库、扩展或自定义绘制和事件处理来实现多点触控功能。这些方法可以帮助我们在WinForms应用程序中创建更具交互性和触摸友好的用户界面。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值