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

论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。
【android 多点MotionEvent的构建,多点操作屏幕,多点触碰屏幕】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(" getMultiEventusedList 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,有空再编写

    推荐阅读