模拟MotionEvent事件

这两天在做模块的单元测试,需要模拟触屏事件,手势操作,下面针对MotionEvent做下代码记录:

下面的事件注入都会调用一个函数:

Instrumentation mInstrumentation;
    
public void sendPointerEvent(int action, Point point) {
        MotionEvent event = MotionEvent.obtain(SystemClock.uptimeMillis(),
        SystemClock.uptimeMillis(), action, point.x, point.y, 0);
        mInstrumentation.sendPointerSync(event);
        event.recycle();
    }

1,MotionEvent.ACTION_DOWN

Down跟UP通常是连着的。

Point selectPoint = new Point(670,470);
sendPointerEvent(MotionEvent.ACTION_DOWN, selectPoint);
sendPointerEvent(MotionEvent.ACTION_UP, selectPoint);

2,MotionEvent.ACTION_MOVE

从一个Down事件开始,中间loop多个Move,最后一个Up事件。

Point from = new Point(150, 650);
Point to = new Point(150, 260);
sendPointerEvent(MotionEvent.ACTION_DOWN, from);
MovePointerEvent(from, to, 10, 10);
sendPointerEvent(MotionEvent.ACTION_UP, to);

这里计算move的步进:

    private int getNextMoveValue(int oldValue, int targetValue, int distance, int step) {
        if (targetValue - oldValue > distance) {
            return oldValue + step;
        } else if (targetValue - oldValue < -distance) {
            return oldValue - step;
        } else {
            return targetValue;
        }
    }

3,手势操作,缩放

private int PINCH_STEP_COUNT = 10;
 
 public void scaleGestureDetector() {
        try {
            final float initialScaleFactor = 1.0f;
            final DisplayMetrics dm = new DisplayMetrics();
            final WindowManager wm =
                (WindowManager)mContext.getSystemService(Context.WINDOW_SERVICE);
            //obtain the display size ,so that to get start and end coordinates.
            wm.getDefaultDisplay().getMetrics(dm);
            final int displayWidth = dm.widthPixels;
            final int displayHeight = dm.heightPixels;
            //from center,pinch to 75% of display.
            final int centerX = displayWidth / 2;
            final int centerY = displayHeight / 2;
            final float[] firstFingerStartCoords = new float[] {centerX + 1.0f, centerY - 1.0f};
            final float[] firstFingerEndCoords =
               new float[] {0.75f * displayWidth, 0.25f * displayHeight};
            //the second point different from the first.
            final float[] secondFingerStartCoords = new float[] {centerX - 1.0f, centerY + 1.0f};
            final float[] secondFingerEndCoords =
               new float[] {0.25f * displayWidth, 0.75f * displayHeight};
            //specify the touch properites.
            final MotionEvent.PointerProperties pp1 = new MotionEvent.PointerProperties();
            pp1.id = 0;
            pp1.toolType = MotionEvent.TOOL_TYPE_FINGER;
            final MotionEvent.PointerProperties pp2 = new MotionEvent.PointerProperties();
            pp2.id = 1;
            pp2.toolType = MotionEvent.TOOL_TYPE_FINGER;
            MotionEvent.PointerProperties[] pointerProperties =
                   new MotionEvent.PointerProperties[]{pp1, pp2};
            //specify the motion properites.
            final MotionEvent.PointerCoords pc1 = new MotionEvent.PointerCoords();
            pc1.x = firstFingerStartCoords[0];
            pc1.y = firstFingerStartCoords[1];
            pc1.pressure = 1;
            pc1.size = 1;
            final MotionEvent.PointerCoords pc2 = new MotionEvent.PointerCoords();
            pc2.x = secondFingerStartCoords[0];
            pc2.y = secondFingerEndCoords[1];
            pc2.pressure = 1;
            pc2.size = 1;

            final long startTime = SystemClock.uptimeMillis();
            long eventTime = startTime;
            final MotionEvent.PointerCoords[] pointerCoords = new MotionEvent.PointerCoords[]{pc1, pc2};

            final MotionEvent firstFingerEvent = MotionEvent.obtain(startTime,
                   eventTime, MotionEvent.ACTION_DOWN, 1, pointerProperties, pointerCoords,
                   0, 0, 1, 1, 0, 0, 0, 0);

            eventTime = SystemClock.uptimeMillis();
            final MotionEvent secondFingerEvent = MotionEvent.obtain(startTime, eventTime,
                   MotionEvent.ACTION_POINTER_DOWN +
                           (pp2.id << MotionEvent.ACTION_POINTER_INDEX_SHIFT),
                   2, pointerProperties, pointerCoords, 0, 0, 1, 1, 0, 0, 0, 0);
            //inject the start down event.
            mInstrumentation.sendPointerSync(firstFingerEvent);
            mInstrumentation.sendPointerSync(secondFingerEvent);

            final float[][] stepsFirstFinger = interpolate(firstFingerStartCoords,
                   firstFingerEndCoords);
            final float[][] stepsSecondFinger = interpolate(secondFingerStartCoords,
                   secondFingerEndCoords);
            //loop the motion of two fingers to the end points.
            for (int i = 0; i < PINCH_STEP_COUNT; i++) {
               eventTime = SystemClock.uptimeMillis();

               pc1.x = stepsFirstFinger[i][0];
               pc1.y = stepsFirstFinger[i][1];
               pc2.x = stepsSecondFinger[i][0];
               pc2.y = stepsSecondFinger[i][1];

               final MotionEvent event = MotionEvent.obtain(startTime, eventTime,
                       MotionEvent.ACTION_MOVE, 2, pointerProperties, pointerCoords,
                       0, 0, 1, 1, 0, 0, 0, 0);
               mInstrumentation.sendPointerSync(event);
               Thread.sleep(TIMEWAITING*4/5);
            }

            eventTime = SystemClock.uptimeMillis();
            final MotionEvent secondFingerUpEvent = MotionEvent.obtain(startTime, eventTime,
                   MotionEvent.ACTION_POINTER_UP, 2, pointerProperties, pointerCoords,
                   0, 0, 1, 1, 0, 0, 0, 0);
            //inject the up event.
            mInstrumentation.sendPointerSync(secondFingerUpEvent);

            eventTime = SystemClock.uptimeMillis();
            final MotionEvent firstFingerUpEvent = MotionEvent.obtain(startTime, eventTime,
                   MotionEvent.ACTION_POINTER_UP, 1, pointerProperties, pointerCoords,
                   0, 0, 1, 1, 0, 0, 0, 0);
            mInstrumentation.sendPointerSync(firstFingerUpEvent);
        }catch (InterruptedException e) {
            e.printStackTrace();
            Thread.currentThread().interrupt();
        }
    }

两个手指移动的差值计算:

    private float[][] interpolate(float[] start, float[] end) {
        float[][] res = new float[PINCH_STEP_COUNT][2];

        for (int i = 0; i < PINCH_STEP_COUNT; i++) {
        res[i][0] = start[0] + (end[0] - start[0]) * i / (PINCH_STEP_COUNT - 1f);
        res[i][1] = start[1] + (end[1] - start[1]) * i / (PINCH_STEP_COUNT - 1f);
        }
        return res;
    }

 

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值