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

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

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

android 多点MotionEvent的构建,多点操作屏幕,多点触碰屏幕_第1张图片

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,有空再编写

你可能感兴趣的:(android)