欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

android 多点MotionEvent的构建,多点操作屏幕,多点触碰屏幕

程序员文章站 2022-07-12 21:20:06
...

论android 多点触碰的构建。可以用于外设对于手机的多点操控,比如说手柄,键鼠等

1.我们先分析一下多个手点击滑动得到的MotionEvent。在view 重写onTouchEvent的方法,打印内容

android 多点MotionEvent的构建,多点操作屏幕,多点触碰屏幕

android 多点MotionEvent的构建,多点操作屏幕,多点触碰屏幕

2.分析的内容,这边不做详细的截图,自己去打印查看,我们分析两个点,开始一个点是Action=ACTION_DOWN,然后move,id就是0,点下第二个点,action=ACTION_POINTER_DOWN(1),id为1,第一个点的id还是0,并且可以看到两个点的坐标都是存在的,也就是这个MotionEvent是带着两个点的,接着释放一个点,这个时候你会看到如果释放的是第二个点,action=ACTION_POINTER_UP(1),如果释放的是第一个点,那么action=ACTION_POINTER_UP(0),当释放最后一个点的时候action=ACTION__UP

3.以此类推,三个点,四个点,就是ACTION_POINTER_DOWN(2)ACTION_POINTER_UP(2),每个点都是有id标识的,下标从0开始,点下的点跟释放的点都是同一个id。

4.创建多点,需要拿到action,sid,坐标。实现逻辑 当down下的时候,记录点下的点的id,id是从0开始,并且如果按下0,按下1,按下2,释放1,再按下id就是1,也就是说从0开始,如果中间某个id不存在就记录为当前的id,当move的时候就沿用这个id,当up的时候就移除这个uselist的对象,


    public void down(int keycode, int x, int y) {
        synchronized (lock) {
            try {
              GamePadEvent target = new GamePadEvent(keycode);
                //把新的target 添加到usedlist里面去,并且设置sid
                if (usedList.size() > 0) {
                    int i;
                    for (i = 0; i < 10; i++) {//写了10就是支持10个点
                        boolean found = false;
                        for (GamePadEvent each : usedList) {
                            if (each.sid == i) {
                                found = true;
                                break;
                            }
                        }
                        if (!found)
                            break;
                    }
                    target.sid = i;
                    usedList.add(i, target);
                } else {
                    target.sid = 0;
                    usedList.add(0, target);
                }
                MotionEvent event = getMultiEvent(target);
               //注入这里不写明,不同环境使用方法不一样,当前应用可以使用下面方法的去测试
               Instrumentation mInst = new Instrumentation();
                        if (event != null)
                            mInst.sendPointerSync(event.getMotionEvent());
            } catch (Exception e) {
                e.printStackTrace();
            }

        }
    }

5.重点是多点的构建,PointerProperties 主要构建sid,就是刚刚保存的id ,从下标0开始算,PointerCoords 主要是构建坐标, MotionEvent.obtain(),方式去构建一个新的MotionEvent。


private MotionEvent getMultiEvent(GamePadEvent target) {
        if (usedList.size() == 0)
            return null;
        long when = SystemClock.uptimeMillis();
        int action = MotionEvent.ACTION_MOVE;
        
        //记录当前按下的点的action是move,up,down,判断点是2个点还是一个点,记录当前的action,方便后面做计算
        if (target.action == MotionEvent.ACTION_DOWN)
            action = usedList.size() > 1 ? MotionEvent.ACTION_POINTER_DOWN : MotionEvent.ACTION_DOWN;

        if (target.action == MotionEvent.ACTION_UP)
            action = usedList.size() > 1 ? MotionEvent.ACTION_POINTER_UP : MotionEvent.ACTION_UP;

        PointerProperties[] pointerProperties = new PointerProperties[usedList.size()];
        PointerCoords[] pointerCoords = new PointerCoords[usedList.size()];
        int index = 0;
        int targetIndex = 0;
        LogUtils.logI(" getMultiEvent  usedList size :" + usedList.size());
        for (GamePadEvent gamePadEvent : usedList) {
            PointerCoords pointerCoord = new PointerCoords();
            pointerCoord.pressure = 1;
            pointerCoord.x = gamePadEvent.x;//x坐标
            pointerCoord.y = gamePadEvent.y;//yx坐标
            pointerCoords[index] = pointerCoord;

            PointerProperties pointerPropertie = new PointerProperties();
            pointerPropertie.id = gamePadEvent.sid;//保存的id
            pointerPropertie.toolType = 1;
            pointerProperties[index] = pointerPropertie;

            if (gamePadEvent.keycode == target.keycode) { 
                targetIndex = index;//记录当前的按下的点的位置,用作计算最后的action
            }
            ++index;
        }
        //这是计算最后的点的action,前面通过多点,单点判断得到了action,就位移计算,等到最后的值,如果是move事件,多点的action还是move,如果是其它两个down,up,
        int actionPoint = (action != MotionEvent.ACTION_MOVE) ? (action + (targetIndex << MotionEvent.ACTION_POINTER_INDEX_SHIFT)) : MotionEvent.ACTION_MOVE;
        
        return MotionEvent.obtain(when, when, actionPoint, usedList.size(), pointerProperties, pointerCoords, 0, 0, 1, 1, 0, 0, InputDevice.SOURCE_TOUCHSCREEN, 0);
    }

6.最后,如果有什么疑问,可以联系我。暂时没有编写demo,有空再编写