Simulate fling gesture in Android ActivityInstrumentationTestCase2

I have an Android view that I discover in order to perform an operation, and I want to write some tests to make sure the gesture works correctly. I tried TouchUtils.dragViewTo and TouchUtils.drag (with very few steps), but none of them seem to trigger an event.

Is there any way to simulate fling gestures?

+6
android android-2.2-froyo
source share
3 answers

Ok, this is a really old question, but posting a solution that worked for me can help others who are looking for this

 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 
+2
source share

From a look at the source of TouchUtils, the problem is that the number of steps is just the number of touch events to generate and does not affect how quickly they occur:

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

It waits for synchronization with the application after each event, so it does not seem to be happening fast enough to run. We can see that from how the GestureDetector recognizes a throw:

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

Therefore, I recommend a custom drag-and-drop method that does not wait for synchronization with every touch move event (we don’t care that the user interface is updated with every drag and drop movement anyway, we just want to generate a transfer). Something like this (not verified):

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

Well, in fact, all I did was comment on the expectation of waiting for unoccupied synchronization in the motion event loop. Choose some reasonable values ​​for the distance traveled and the number of steps, and this should work. If this is not the case, you may need to wait a short time in the loop to withstand events a bit if they are too fast.

0
source share

Not sure if this is what you are looking for, but here is an example test I wrote to make sure the fling engine works with a custom gallery component.

 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
source share

All Articles