De su análisis de la fuente TouchUtils, el problema aquí es que el número de pasos es sólo el número de eventos de toque para generar y no afecta a la rapidez con que se planteen:
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();
}
Está esperando para una sincronización con la aplicación después de cada evento, por lo que no parece que eso ocurra lo suficientemente rápido como para lanzarse. Podemos ver que a partir de la forma en la GestureDetector reconoce una aventura:
// 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);
}
por lo que recomiendo un método personalizado de arrastre que no espera a que se sincroniza en cada evento movimiento táctil (no nos importa que las actualizaciones de la interfaz de usuario con cada uno arrastrar mover de todos modos, solo queremos generar una aventura). Algo como esto (no probado):
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();
}
Bueno, en realidad todo lo que hice no había comente la espera de sincronización de inactividad en el bucle de eventos de movimiento. Elija algunos valores razonables para la distancia recorrida y el recuento de pasos, y eso debería funcionar. Si no es así, es posible que necesites una pequeña espera en el ciclo para espaciar ligeramente los eventos si van demasiado rápido.
¿no es entonces probar las cosas mal? Lo que le gustaría probar es la acción que se realiza cuando se produce el gesto de arrojar. Supongo que el gesto arrojado es solo un evento simple con un oyente de evento adjunto. Dentro del oyente del evento, probablemente invoque alguna función, y esa es esa función que le gustaría probar. – Nailuj
Ya estoy probando la función de salida, pero quiero saber que funciona correctamente con el gesto fling, ya que importa en qué dirección ocurre el gesto y quiero probar la lógica de eso, ya que el oyente interpreta la dirección de la aventura. Parece extraño que pueda interactuar con la vista simulando tocar y arrastrar, pero ninguna de las operaciones de arrastre parece realizar una aventura. Me pregunto si me estoy perdiendo algo sutil – Kevin
Ok, ya veo. Ahora bien, esto es solo que estoy pensando en voz alta (y no estoy muy familiarizado con las pruebas en Android, por lo que podría haber problemas que no veo con este enfoque), pero si quieres probar la lógica de interpretar el gesto, no podría ¿Acabas de poner otra capa de abstracción? En su manejador de eventos 'onFling', simplemente pasa todos los argumentos a su propia función' processFlingEvent (MotionEvent, MotionEvent, float, float) ', ¿cuál debería ser más fácil de probar? – Nailuj