2010-10-22 2 views
6

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

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

+1

Разве вы затем проверить неправильную вещь? То, что вам нужно было испытать, - это действие, выполняемое при появлении жестов fling. Я предполагаю, что бегущий жест - это простое событие с приложением прослушивания событий. Внутри прослушивателя событий вы, вероятно, вызываете некоторую функцию - и это функция _that_, которую вы хотите протестировать. – Nailuj

+0

Я уже тестирую выходную функцию, но хочу знать, что она правильно работает с жестом fling, поскольку имеет значение, в каком направлении происходит жест, и я хочу проверить логику этого, поскольку слушатель интерпретирует направление перехода. Кажется странным, что я могу взаимодействовать с представлением, моделируя прикосновение и перетаскивание, но ни одна из операций перетаскивания, похоже, не выполняет бросок. Мне просто интересно, не хватает ли я чего-то тонкого – Kevin

+1

Хорошо, я вижу. Теперь это только я, думая громко (и я не слишком хорошо знаком с тестированием на Android, так что могут быть проблемы, которые я не вижу с этим подходом), но если вы хотите проверить логику интерпретации жестов, Ты просто положил еще один слой абстракции? В обработчике событий onFling вы просто передаете все аргументы в свою собственную 'processFlingEvent (MotionEvent, MotionEvent, float, float)' функцию, которая тогда должна быть легче протестировать? – Nailuj

ответ

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

Он ждет синхронизации с приложение после каждого события, поэтому не похоже, что это происходит достаточно быстро, чтобы бежать. Мы можем видеть, что от того, как 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); 
      } 

Так что я рекомендую метод пользовательского перетаскивания, не ждать, пока синхронизируется на каждом сенсорном случае перемещения (мы не заботимся о том, что обновления пользовательского интерфейса с каждым drag move anyway, мы просто хотим генерировать бросок). Что-то вроде этого (не проверено):

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

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

0

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

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

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

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 
Смежные вопросы