以编程方式触发 ACTION_POINTER_DOWN 事件

Trigger ACTION_POINTER_DOWN event programmatically

想要触发 on two fingers down 事件几毫秒。

我可以使用以下代码触发简单的触摸事件:

 objImageView.getLocationOnScreen(coords);
                    int xa = coords[0];
                    int ys = coords[1];
                    objImageView.dispatchTouchEvent(MotionEvent.obtain(0, 0, MotionEvent.ACTION_DOWN, xa, ys, 0.5f, 5, 0, 1, 1, 0, 0));
                    objImageView.dispatchTouchEvent(MotionEvent.obtain(0, 0, MotionEvent.ACTION_MOVE, xa, ys, 0.5f, 5, 0, 1, 1, 0, 0));
                    objImageView.dispatchTouchEvent(MotionEvent.obtain(0, 0, MotionEvent.ACTION_UP, xa, ys, 0.5f, 5, 0, 1, 1, 0, 0));

现在,如果我尝试对 ACTION_POINTER_DOWN 执行相同的操作,则什么也没有发生。这是我的代码:

  int[] coords = new int[2];
        parentLayout.getLocationOnScreen(coords);
        int xa = coords[0];
        int ys = coords[1];
        parentLayout.dispatchTouchEvent(MotionEvent.obtain(0, 0, MotionEvent.ACTION_POINTER_DOWN, xa, ys, 0.5f, 5, 0, 1, 1, 0, 0));
        parentLayout.dispatchTouchEvent(MotionEvent.obtain(0, 0, MotionEvent.ACTION_MOVE, xa, ys, 0.5f, 5, 0, 1, 1, 0, 0));
        parentLayout.dispatchTouchEvent(MotionEvent.obtain(0, 0, MotionEvent.ACTION_POINTER_UP, xa, ys, 0.5f, 5, 0, 1, 1, 0, 0));

我想触发同一事件,该事件在用户将两根手指放下并保持几毫秒时调用。

Documentation said that: "A gesture starts with a motion event with ACTION_DOWN that provides the location of the first pointer down. As each additional pointer that goes down or up, the framework will generate a motion event with ACTION_POINTER_DOWN or ACTION_POINTER_UP accordingly." so You need trigger simple touch event at first. And take a look at this 个问题。

您应该生成这样的序列:ACTION_DOWN -> ACTION_POINTER_DOWN -> 可选的小延迟 -> ACTION_POINTER_UP -> ACTION_UP.

您还应该为第二个指针正确设置指针索引(和其他元数据),否则手势检测代码可能无法判断 ACTION_POINTER_DOWN 二次按下是在描述辅助手指,而不是主手指。

使用this method填写ACTION_POINTER_DOWN描述第二次按下的所有必要信息。 确保传递正确 pointerProperties!

要模拟 "two fingers",您需要像现在一样创建一个包含多个 一个 指针的运动事件。

为此,请使用支持多个指针的 MotionEvent obtain 变体,如记录 here

MotionEvent obtain (long downTime, 
                long eventTime, 
                int action, 
                int pointerCount, 
                PointerProperties[] pointerProperties, 
                PointerCoords[] pointerCoords, 
                int metaState, 
                int buttonState, 
                float xPrecision, 
                float yPrecision, 
                int deviceId, 
                int edgeFlags, 
                int source, 
                int flags)

首先,您应该为第一个手指发送一个事件(就像您所做的那样),当您要模拟时 MotionEvent.ACTION_POINTER_DOWN您应该使用上面的 obtain 变体。

字段很容易解释,确保参数是:

  1. 指针计数 = 2
  2. pointerProperties = [firstFingerPointerProperties, secondFingerPointerProperties]
  3. pointerCoords = [firstFingerPointerCoords, secondFingerPointerCoords]

这是一个旧话题,但由于 none 的答案是完整的,所以在这里为未来的人们添加更多信息。和作者一样,我想模拟两次触摸,即使我的顺序是:

ACTION_DOWN(0), PointerCount = 1
ACTION_POINTER_DOWN(5), PointerCount = 2
ACTION_POINTER_UP(6), PointerCount = 2
ACTION_UP(1), PointerCount = 1

它根本不起作用,我才明白,你需要通过指针计数来移动动作。

if ((action == ACTION_POINTER_DOWN || action == ACTION_POINTER_UP) && pointerCount > 1)
   action |= 256 << (pointerCount - 2);

换句话说,动作值变为

ACTION_DOWN(0), PointerCount = 1
ACTION_POINTER_DOWN(261), PointerCount = 2
ACTION_POINTER_UP(262), PointerCount = 2
ACTION_UP(1), PointerCount = 1

直到那时它才开始为我工作