2015-03-13 28 views

回答

2

由于@Daniel建议,我创建MotionEvents的定制版本,因为使用多个手指时,你必须注入ACTION_POINTER_DOWN/UP,而不是ACTION_DOWN/UP。 我创建LinearSwipe的twoFinger版本,像这样:

private static Swiper.Status sendLinearSwipe(UiController uiController, 
              float[] startCoordinates, 
              float[] startCoordinatesSecondFinger, 
              float[] endCoordinates, 
              float[]endCoordinatesSecondFinger, 
              float[] precision, 
              float[] precisionSecond, 
              int duration) { 
    checkNotNull(uiController); 
    checkNotNull(startCoordinates); 
    checkNotNull(startCoordinatesSecondFinger); 
    checkNotNull(endCoordinates); 
    checkNotNull(endCoordinatesSecondFinger); 
    checkNotNull(precision); 
    checkNotNull(precisionSecond); 

    float[][] steps = interpolate(startCoordinates, endCoordinates, SWIPE_EVENT_COUNT); 
    float[][] stepsSecondFinger = interpolate(startCoordinatesSecondFinger, endCoordinatesSecondFinger, SWIPE_EVENT_COUNT); 
    final int delayBetweenMovements = duration/steps.length; 
    final int delayBetweenMovementsSecondFinger = duration/stepsSecondFinger.length; 

    int maxLength=Math.min(steps.length, stepsSecondFinger.length); 

    MotionEvent downEvent; 
    downEvent = MotionEvents.sendDown(uiController, steps[0], precision,true).down; 
    MotionEvent downEventSecondFinger; 
    downEventSecondFinger = MotionEvents.sendDown(uiController,stepsSecondFinger[0], precisionSecond,false).down; 

    try { 
     for (int i = 1; i < maxLength; i++) { 

      if (sendMovement(uiController, steps[i], downEvent)) return Status.FAILURE; 
      if (sendMovement(uiController, stepsSecondFinger[i], downEventSecondFinger)) return Status.FAILURE; 


      long desiredTime = downEvent.getDownTime() + delayBetweenMovements * i; 
      long desiredTimeSecondFinger = downEventSecondFinger.getDownTime() + delayBetweenMovementsSecondFinger * i; 

      long timeUntilDesired = desiredTime - SystemClock.uptimeMillis(); 
      long timeUntilDesiredSecondFinger = desiredTimeSecondFinger - SystemClock.uptimeMillis(); 
      loopMainThread(uiController, timeUntilDesired); 
      loopMainThread(uiController, timeUntilDesiredSecondFinger); 

     } 

     if (!MotionEvents.sendUp(uiController, downEventSecondFinger, endCoordinatesSecondFinger,false)) { 
      Log.e(TAG, "Injection of up event as part of the swipe failed. Sending cancel event."); 
      MotionEvents.sendCancel(uiController, downEventSecondFinger); 
      return Swiper.Status.FAILURE; 
     } 
    } finally { 
     downEvent.recycle(); 
     downEventSecondFinger.recycle(); 
    } 
    return Swiper.Status.SUCCESS; 
} 

private static void loopMainThread(UiController uiController, long timeUntilDesired) { 
    if (timeUntilDesired > 10) { 
     uiController.loopMainThreadForAtLeast(timeUntilDesired); 
    } 
} 

private static boolean sendMovement(UiController uiController, float[] step, MotionEvent downEvent) { 
    if (!MotionEvents.sendMovement(uiController, downEvent, step)) { 
     Log.e(TAG, "Injection of move event as part of the swipe failed. Sending cancel event."); 
     MotionEvents.sendCancel(uiController, downEvent); 
     return true; 
    } 
    return false; 
} 

现在,它完美的作品!由于@Daniel

+1

您是否还可以在您的示例中包含interpolate方法? – Adrian 2016-03-23 10:03:45

1

咖啡不提供该功能,但你可以通过

  • 注射两降事件
  • 注入几双运动事件,每一个手指
  • 注入两个上事件做自己

意式浓缩咖啡有一些实用工具可以使它更容易。特别是,MotionEvents类有一些辅助方法来创建和注入这些低级事件。

您可能要参考sendLinearSwipe代码包含大部分逻辑的单点触摸刷卡。

如果您将其编写为ViewAction,它将完全适合Espresso框架(例如,您可以轻松地等待空闲资源)。

+0

谢谢,我现在的工作。但是,当我注入两个事件时它失败了。但是,如果我只注入一个事件,它可以正常工作:) – HowieH 2015-03-18 14:16:57