在Android ActivityInstrumentationTestCase2中模拟一个fling手势

Kev*_*vin 6 android android-2.2-froyo

我有一个Android视图,我正在检测执行操作的手势,我想编写一些测试来验证手势是否正常工作.我曾尝试TouchUtils.dragViewToTouchUtils.drag(有极少数的步骤),但这些都不似乎触发事件.

有没有办法模拟投掷手势?

Mat*_*all 0

从 TouchUtils 源代码来看,这里的问题是步数只是要生成的触摸事件的数量,并不影响它们发生的速度:

    for (int i = 0; i < stepCount; ++i) {
        y += yStep;
        x += xStep;
        eventTime = SystemClock.uptimeMillis();
        event = MotionEvent.obtain(downTime, eventTime, MotionEvent.ACTION_MOVE, x, y, 0);
        inst.sendPointerSync(event);
        inst.waitForIdleSync();
    }
Run Code Online (Sandbox Code Playgroud)

每次事件发生后,它都会等待与应用程序同步,因此似乎发生的速度不够快,无法快速进行。从 GestureDetector 如何识别 fling 可以看出:

           // A fling must travel the minimum tap distance
            final VelocityTracker velocityTracker = mVelocityTracker;
            velocityTracker.computeCurrentVelocity(1000);
            final float velocityY = velocityTracker.getYVelocity();
            final float velocityX = velocityTracker.getXVelocity();

            if ((Math.abs(velocityY) > ViewConfiguration.getMinimumFlingVelocity())
                    || (Math.abs(velocityX) > ViewConfiguration.getMinimumFlingVelocity())){
                handled = mListener.onFling(mCurrentDownEvent, mCurrentUpEvent, velocityX, velocityY);
            }
Run Code Online (Sandbox Code Playgroud)

因此,我建议使用一种自定义拖动方法,该方法不等待每个触摸移动事件的同步(无论如何,我们不关心 UI 随每个拖动移动而更新,我们只想生成一次滑动)。像这样的东西(未测试):

public static void fling(InstrumentationTestCase test, float fromX, float toX, float fromY,
        float toY, int stepCount) {
    Instrumentation inst = test.getInstrumentation();

    long downTime = SystemClock.uptimeMillis();
    long eventTime = SystemClock.uptimeMillis();

    float y = fromY;
    float x = fromX;

    float yStep = (toY - fromY) / stepCount;
    float xStep = (toX - fromX) / stepCount;

    MotionEvent event = MotionEvent.obtain(downTime, eventTime,
            MotionEvent.ACTION_DOWN, fromX, y, 0);
    inst.sendPointerSync(event);
    inst.waitForIdleSync();

    for (int i = 0; i < stepCount; ++i) {
        y += yStep;
        x += xStep;
        eventTime = SystemClock.uptimeMillis();
        event = MotionEvent.obtain(downTime, eventTime, MotionEvent.ACTION_MOVE, x, y, 0);
        inst.sendPointerSync(event);
        //inst.waitForIdleSync();
    }

    eventTime = SystemClock.uptimeMillis();
    event = MotionEvent.obtain(downTime, eventTime, MotionEvent.ACTION_UP, fromX, y, 0);
    inst.sendPointerSync(event);
    inst.waitForIdleSync();
}
Run Code Online (Sandbox Code Playgroud)

好吧,实际上我所做的就是注释掉运动事件循环中等待空闲同步的部分。为行驶距离和步数选择一些合理的值,这应该有效。如果没有,您可能需要在循环中短暂等待,以稍微间隔开事件(如果它们来得太快)。