Android基础 多点触控事件处理方案

本文详细解析了触摸屏中PointerId和PointerIndex的区别,解释了每根手指在触控过程中如何分配唯一的PointerId,以及PointerIndex在多点触控场景下如何随手指状态动态变化。并提供了代码示例,展示了如何在实际应用中使用这两个概念。
PointerId 和 Index 区别:
PointerId

每根手指从按下、移动到离开屏幕,每个手指都会拥有一个固定PointerId,PointerId的值可以是任意的值。

PointerIndex

每根手指从按下、移动到离开屏幕,每根手指在每一个事件的Index可能是不固定的,因为受到其它手指的影响。比如,A跟B两根手指同时按在屏幕上,此时A的PointerIndex为0,B的则为1.当A先离开屏幕时,B的PointerIndex则变为了0.
但是,PointerIndex的值的不是任意的,它必须在[0,PointerCount-1]的范围内。其中PointerCount为参与触控的手指数量。

PointerId是固定不变的,每个手指是拥有一个固定PointerId;
PointerIndex是会变化的;

//参数中的 pointerIndex 就是 actionIndex
int id = event.getPointerId(event.getActionIndex());
....
//在按下触发按键时候记录PointerId
pointerIdHashMap.put(id, temp.key);

此处代码是只是onTouchEvent的部分

private void onTouchEvent(View view, MotionEvent event) {
        // 编辑模式
        if (isEditMode) {
            setNewPositionByEvent(event);
            return;
        }
        int action = event.getActionMasked();
        switch (action) {
            case MotionEvent.ACTION_DOWN:
            case MotionEvent.ACTION_POINTER_DOWN:
                int id = event.getPointerId(event.getActionIndex());
                //获取是否在按键上
                AreaInfo temp = getAreaInfoByEvent(event);
                if (temp != null) {
                    if (!TextUtils.isEmpty(temp.key)) {
//                        Logger.e(action + " id: " + id + ":" + temp.key);
                        pointerIdHashMap.put(id, temp.key);

                        setSelectedState(temp.key, true);
                        set.add(temp.key);

                        // TODO: 2019/12/11 触发 连击和锁定
                        int value = getExtendType(temp.key);
                        if ((value & ParamInfo.TYPE_SERIES) == ParamInfo.TYPE_SERIES) {
                            if (turbSet.contains(temp.key)) {
                                turbSet.remove(temp.key);
                            } else {
                                turbSet.add(temp.key);
                            }
                            if (!handler.hasMessages(MESSAGE_TURB_CLICK)) {
                                handler.sendEmptyMessage(MESSAGE_TURB_CLICK);
                            }
                        } else if ((value & ParamInfo.TYPE_LOCK) == ParamInfo.TYPE_LOCK) {
                            if (lockSet.contains(temp.key)) {
                                lockSet.remove(temp.key);
                            } else {
                                lockSet.add(temp.key);
                            }
                        }
                        if ((value & ParamInfo.TYPE_SLIDE_OUT_TRIGGER) == ParamInfo.TYPE_SLIDE_OUT_TRIGGER) {
                            downX = event.getRawX();
                            downY = event.getRawY();
                        } else if ((value & ParamInfo.TYPE_LONGPRESS_TRIGGER) == ParamInfo.TYPE_LONGPRESS_TRIGGER) {
                            downTime = System.currentTimeMillis();
                        }
                        bitValue &= directionMask;
                        bitValue = adjustPressState(bitValue);
                        iNativeCode.inputNativeKey(0, 0, bitValue);
                    }
                }
                break;
            case MotionEvent.ACTION_MOVE:
                id = event.getPointerId(event.getActionIndex());
                String key = pointerIdHashMap.get(id);
                temp = getAreaInfoByEvent(event);
                if (temp != null) {
                    if (!TextUtils.isEmpty(temp.key)) {
                      if (TextUtils.isEmpty(key)) {
                            set.add(temp.key);
                            setSelectedState(temp.key, true);
                            bitValue &= directionMask;
                            // 处理锁定集合
                            bitValue = adjustPressState(bitValue);
                            iNativeCode.inputNativeKey(0, 0, bitValue);
                            pointerIdHashMap.put(id, temp.key);
                        } else if (!TextUtils.equals(temp.key, key)) {
                            set.add(temp.key);
                            setSelectedState(temp.key, true);
                            bitValue &= directionMask;
                            // 处理锁定集合
                            bitValue = adjustPressState(bitValue);
                            iNativeCode.inputNativeKey(0, 0, bitValue);
                        }
                    }
                }
                break;
            case MotionEvent.ACTION_POINTER_UP:
            case MotionEvent.ACTION_CANCEL:
            case MotionEvent.ACTION_UP:
                id = event.getPointerId(event.getActionIndex());
                key = pointerIdHashMap.get(id);
//                Logger.e(action + " id: " + id + ":" + key);
                if (!TextUtils.isEmpty(key)) {
                    setSelectedState(key, false);
                    set.remove(key);
                    pointerIdHashMap.remove(id);
                    if (pointerIdHashMap.size() == 0) {
                        for (String a : set) {
                            setSelectedState(a, false);
                        }
                        set.clear();
                    }
                    // TODO: 2019/12/11 抬起时触发 连击和锁定操作
                    int value = getExtendType(key);
                    if ((value & ParamInfo.TYPE_CLICK_TRIGGER) == ParamInfo.TYPE_CLICK_TRIGGER) {
                        if ((value & ParamInfo.TYPE_LOCK) == ParamInfo.TYPE_LOCK) {
                            setSelectedState(key, lockSet.contains(key));
                        }
                    } else if ((value & ParamInfo.TYPE_LONGPRESS_TRIGGER) == ParamInfo.TYPE_LONGPRESS_TRIGGER) {
                        if ((value & ParamInfo.TYPE_SERIES) == ParamInfo.TYPE_SERIES) {
                            turbSet.remove(key);
                        } else if ((value & ParamInfo.TYPE_LOCK) == ParamInfo.TYPE_LOCK) {
                            if (downTime > 0 && System.currentTimeMillis() - downTime < 1000) {
                                lockSet.remove(key);
                            } else if (downTime > 0 && System.currentTimeMillis() - downTime >= 1000) {
                                setSelectedState(key, true);
                            }
                        }
                    } else if ((value & ParamInfo.TYPE_SLIDE_OUT_TRIGGER) == ParamInfo.TYPE_SLIDE_OUT_TRIGGER) {
                        if (downY > 0 && event.getRawY() - downY < 50 * density) {
                            if ((value & ParamInfo.TYPE_SERIES) == ParamInfo.TYPE_SERIES) {
                                turbSet.remove(key);
                            } else if ((value & ParamInfo.TYPE_LOCK) == ParamInfo.TYPE_LOCK) {
                                lockSet.remove(key);
                            }
                        } else if (downY > 0 && event.getRawY() - downY >= 50 * density) {
                            if ((value & ParamInfo.TYPE_LOCK) == ParamInfo.TYPE_LOCK) {
                                setSelectedState(key, true);
                            }
                        }
                    }
                }
                bitValue &= directionMask;
                bitValue = adjustPressState(bitValue);
                iNativeCode.inputNativeKey(0, 0, bitValue);
                break;
        }
    }
image.png
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值