Имитация жеста броска в Android ActivityInstrumentationTestCase2 - PullRequest
6 голосов
/ 22 октября 2010

У меня есть представление Android, на котором я обнаруживаю бросок для выполнения операции, и я хочу написать несколько тестов, чтобы убедиться, что жест работает правильно.Я пробовал TouchUtils.dragViewTo и TouchUtils.drag (с очень небольшим количеством шагов), но ни один из них, кажется, не вызывает событие.

Есть ли способ симулировать жест броска?

Ответы [ 3 ]

2 голосов
/ 03 октября 2012

Хорошо, это действительно старый вопрос, но размещение решения, которое сработало для меня, может помочь другим, кто придет в поисках этого

int[] xy = new int[2];
View v = currentActivity.getCurrentFocus();
v.getLocationOnScreen(xy);
final int viewWidth = v.getWidth();
final int viewHeight = v.getHeight();
final float x = xy[0] + (viewWidth / 2.0f);
float fromY = xy[1] + (viewHeight / 2.0f);
int screenWidth = currentActivity.getWindowManager().getDefaultDisplay().getWidth();    
//Drag from centre of screen to Leftmost edge of display
TouchUtils.drag(this, (screenWidth - 1), x,  fromY, fromY , 5); //Vary the last parameter to sdjust speed of fling
0 голосов
/ 24 августа 2011

не уверен, что это то, что вы ищете, но вот пример теста, который я написал, чтобы убедиться, что жест броска работает с пользовательским компонентом галереи.

public void testLeftSwipe() {
    int initialSelectedItemPosition = mGallery.getSelectedItemPosition();

    Rect r = new Rect();
    mGallery.getGlobalVisibleRect(r);

    float fromX = r.centerX();
    float toX = r.centerX() - (r.width() / 4);
    float fromY = r.centerY();
    float toY = r.centerY();
    int stepCount = 10;

    TouchUtils.drag(this, fromX, toX, fromY, toY, stepCount);

    assertTrue(mGallery.getSelectedItemPosition() > initialSelectedItemPosition);
}
0 голосов
/ 13 июня 2011

При взгляде на источник 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();
    }

Ожидание синхронизациис приложением после каждого события, так что не похоже, что это происходит достаточно быстро, чтобы бросить.Это видно из того, как GestureDetector распознает сброс:

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

Поэтому я рекомендую использовать специальный метод перетаскивания, который не ожидает синхронизацию при каждом событии перемещения касания (нам все равно, что пользовательский интерфейс обновляетсяв любом случае, с каждым движением перетаскивания мы просто хотим создать бросок).Примерно так (не проверено):

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();
}

Ну, на самом деле все, что я там делал, это закомментировал ожидание холостого хода в цикле событий движения.Выберите некоторые разумные значения для пройденного расстояния и количества шагов, и это должно сработать.Если этого не произойдет, вам может потребоваться короткое ожидание в цикле, чтобы немного разметить события, если они происходят слишком быстро.

...