Android Espresso,如何继续执行onLongClick和slideDown?

时间:2016-11-23 08:12:13

标签: java android testing android-espresso

我的意思是,我可以按顺序执行这两个动作,但是在中间有一个ACTION_UP MotionEvent我删除了我在视图上使用的OnTouchListener

在我的情况下,我需要避免触发该事件。

我有一个带有玩家的运动场,其中一个用例是在longClick之后移动玩家,该功能运行良好,但我无法在测试中重现该功能。

No TouchListener until onLongClick

以下是我要测试的类的代码,我试图压缩与该问题相关的所有相关代码。

public class FootballFieldLayout extends RelativeLayout implements View.OnTouchListener {
    [...]
    public void addPlayer(FieldPlayer player) {
        final FieldPlayerView fpv = new FieldPlayerView(getContext(), player);
        addView(fpv);
        fpv.setOnLongClickListener(new OnLongClickListener() {
            @Override
            public boolean onLongClick(View v) {
                v.setOnTouchListener(FootballFieldLayout.this);
                    return true;
                }
            });
    }
    [...]
    public float dX=NO_DELTA, dY=NO_DELTA;

    @Override
    public boolean onTouch(View view, MotionEvent event) {
        switch (event.getAction()) {

            case MotionEvent.ACTION_MOVE:
                if(dX == NO_DELTA || dY == NO_DELTA){ setDelta(view, event); }
                view.animate()
                    .x(event.getRawX() + dX)
                    .y(event.getRawY() + dY)
                    .setDuration(0)
                    .start();
                    break;
            case MotionEvent.ACTION_UP:
                view.setOnTouchListener(null);
                resetDelta();
                break;
            default:
                return false;
        }
        return true;
    }
}

这是测试

public class MoveOnLongClickActivityTest {
    [...]
    @Test
    public void playerCanBeMovedVerticallyAfterLongClick() throws InterruptedException {
        onView(withId(R.id.activity_field)).check(matches(isDisplayed()));
        View view = mActivityRule.getActivity().findViewById(R.id.test_player);

        float[] beginCoord = {view.getX(), view.getY()};
        onView(withId(R.id.test_player)).perform(longClick());
        onView(withId(R.id.test_player)).perform(swipeDown());
        float[] endCoord = {view.getX(), view.getY()};

        assertThat(beginCoord[1], not(equalTo(endCoord[1])));
    }
}

我总是使用框架的ViewActions或使用来自其他人改变某些东西的食谱,但我从未尝试过构建复杂的ViewAction而且我有点迷失。

1 个答案:

答案 0 :(得分:2)

我已经在我的问题下看到了你的意见。事实上,我目前遇到了同样的问题(INJECT_EVENTS权限,我所有的解决方法都无法解决)。我在半年前使用过该代码,它对我没有任何问题。

我可以为您提出其他解决方案,但我并非100%确定它会起作用。因为我现在已经像超快速创造了它。我可能有更多的时间来看待它。

然而尝试这个解决方案:

  1. 尝试编写自己的GeneralSwipeAction。看一下构造函数:

    public GeneralSwipeAction(Swiper swiper, CoordinatesProvider startCoordinatesProvider, CoordinatesProvider endCoordinatesProvider, PrecisionDescriber precisionDescriber) {
        this.swiper = swiper;
        this.startCoordinatesProvider = startCoordinatesProvider;
        this.endCoordinatesProvider = endCoordinatesProvider;
        this.precisionDescriber = precisionDescriber;
    }
    
  2. 因此,开始/结束点的x,y位置通过CoordinatesProvider类发送。它是一个返回浮点数组的接口。数组中的第一个浮点数表示x,第二个浮点数表示y。

    1. 创建自己的实现坐标提供程序的类:

      import android.support.test.espresso.action.CoordinatesProvider;
      import android.view.View;
      
      public class CustomisableCoordinatesProvider implements CoordinatesProvider {
      
          private int x;
          private int y;
      
          public CustomisableCoordinatesProvider(int x, int y) {
              this.x = x;
              this.y = y;
          }
      
          @Override
          public float[] calculateCoordinates(View view) {
              return new float[]{x,y};
          }
      }
      
    2. 实现使用此CustomisableCoordinatesProvider执行拖动的自定义ViewAction:

      public static ViewAction drag(int startX, int startY, int endX, int endY) {
          return new GeneralSwipeAction(
              Swipe.FAST,
              new CustomisableCoordinatesProvider(startX, startY),
              new CustomisableCoordinatesProvider(endX, endY),
              Press.FINGER);
      }
      
    3. 并试着像这样使用它:

      onView(withId(R.id.test_player)).perform(drag(0, 100, 0, 100));
      
    4. 我还没有测试过它。但它指向正确的方向可能会起作用或帮助你。尝试一下,告诉我它是否有效,我很好奇自己:)