Input系统学习-----MotionEvent的构造

我们来查看下2个触碰点的MotionEvent  log

07-04 09:45:01.052  6686  6686 D test614 : MotionEvent { action=ACTION_DOWN, act

ionButton=0, id[0]=0, x[0]=331.69287, y[0]=619.67725, toolType[0]=TOOL_TYPE_FING

ER, buttonState=0, metaState=0, flags=0x0, edgeFlags=0x0, pointerCount=1, histor

ySize=0, eventTime=277113574, downTime=277113574, deviceId=8, source=0x1002 }

07-04 09:45:01.800  6686  6686 D test614 : MotionEvent { action=ACTION_POINTER_D

OWN(1), actionButton=0, id[0]=0, x[0]=331.69287, y[0]=619.67725, toolType[0]=TOO

L_TYPE_FINGER, id[1]=1, x[1]=801.2581, y[1]=1427.2566, toolType[1]=TOOL_TYPE_FIN

GER, buttonState=0, metaState=0, flags=0x0, edgeFlags=0x0, pointerCount=2, histo

rySize=0, eventTime=277114572, downTime=277113574, deviceId=8, source=0x1002 }

07-04 09:45:02.433  6686  6686 D test614 : MotionEvent { action=ACTION_POINTER_U

P(0), actionButton=0, id[0]=0, x[0]=331.69287, y[0]=619.67725, toolType[0]=TOOL_

TYPE_FINGER, id[1]=1, x[1]=801.2581, y[1]=1427.2566, toolType[1]=TOOL_TYPE_FINGE

R, buttonState=0, metaState=0, flags=0x0, edgeFlags=0x0, pointerCount=2, history

Size=0, eventTime=277115194, downTime=277113574, deviceId=8, source=0x1002 }

07-04 09:45:03.816  6686  6686 D test614 : MotionEvent { action=ACTION_UP, actio

nButton=0, id[0]=1, x[0]=801.2581, y[0]=1427.2566, toolType[0]=TOOL_TYPE_FINGER,

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

ze=0, eventTime=277116576, downTime=277113574, deviceId=8, source=0x1002 }

MotionEvent打印的code

    public String toString() {

        StringBuilder msg = new StringBuilder();

        msg.append("MotionEvent { action=").append(actionToString(getAction()));

        final int pointerCount = getPointerCount();

        for (int i = 0; i < pointerCount; i++) {

            msg.append(", id[").append(i).append("]=").append(getPointerId(i));

            msg.append(", x[").append(i).append("]=").append(getX(i));

            msg.append(", y[").append(i).append("]=").append(getY(i));

            msg.append(", toolType[").append(i).append("]=").append(

                    toolTypeToString(getToolType(i)));

        }

        msg.append(", buttonState=").append(MotionEvent.buttonStateToString(getButtonState()));

        msg.append(", metaState=").append(KeyEvent.metaStateToString(getMetaState()));

        msg.append(", flags=0x").append(Integer.toHexString(getFlags()));

        msg.append(", edgeFlags=0x").append(Integer.toHexString(getEdgeFlags()));

        msg.append(", pointerCount=").append(pointerCount);

        msg.append(", historySize=").append(getHistorySize());

        msg.append(", eventTime=").append(getEventTime());

        msg.append(", downTime=").append(getDownTime());

        msg.append(", deviceId=").append(getDeviceId());

        msg.append(", source=0x").append(Integer.toHexString(getSource()));

        msg.append(" }");

        return msg.toString();

}

action=ACTION_POINTER_UP(0) 后面显示了index,就知道了是哪个点的操作,根据index可以获得id,当屏幕上有2个点其中一个up了,系统是怎么知道哪一个点up了呢?根据id,坐标,就可以定位到是少(多)了哪个点。

对于ACTION_MOVE,由于经常存在多个点一起move,所以没有必要进行区分,

    public final int getActionIndex() {

        return (nativeGetAction(mNativePtr) & ACTION_POINTER_INDEX_MASK)

                >> ACTION_POINTER_INDEX_SHIFT;

}

所以move的index一般都是 0

由于多个点的数据保存在MotionEvent的内部数组中,通过index去获取各数据,一个index的位置up后,就出现了一个空位,数组结构依次位移。

应用在处理多点事件的时候,由于要处理不断变化的index,有的操作比较复杂,处理的不好,就会出现断触等等点击功能bug

在进行 injectInputEvent的时候,需要构造MotionEvent,管理和控制好各点数据即可,

以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;

        }

        Pointer pointer = pointersState.get(pointerIndex);

        pointer.setPoint(point);

        pointer.setPressure(pressure);

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

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

        if (pointerCount == 1) {

            if (action == MotionEvent.ACTION_DOWN) {

                lastTouchDown = now;

            }

        } else {

            // 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);

}

    public int update(MotionEvent.PointerProperties[] props, MotionEvent.PointerCoords[] coords) {

        int count = pointers.size();

        for (int i = 0; i < count; ++i) {

            Pointer pointer = pointers.get(i);

            // id 0 is reserved for mouse events

            props[i].id = pointer.getLocalId();

            Point point = pointer.getPoint();

            coords[i].x = point.getX();

            coords[i].y = point.getY();

            coords[i].pressure = pointer.getPressure();

        }

        cleanUp();

        return count;

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值