Android Espresso,如何执行onLongClick和slideDown Continue? [英] Android Espresso, How can I perform onLongClick and slideDown continued?

查看:83
本文介绍了Android Espresso,如何执行onLongClick和slideDown Continue?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I mean, I can perform the two actions sequentially but in the middle there is an ACTION_UP MotionEvent where I removed the OnTouchListener I'm using on the view

就我而言,我需要避免触发该事件.

In my case I need to avoid trigger that event.

我在一个运动场上有球员,用例之一是在longClick之后移动球员,该功能运作良好,但我无法在测试中重现该功能.

I have a sport field with players, one of the Use Cases is move a player after a longClick, the feature works well but I can’t reproduce the feature in the tests.

这是我要测试的班级代码,我试图浓缩与问题相关的所有相关代码.

Here is the code of the class I want to test, I tried to condensed all the relevant code associated to the question.

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

我总是使用框架的ViewAction或使用其他人的食谱来更改某些内容,但我从未尝试构建复杂的ViewAction,我有点迷失了.

I always use the ViewActions of the framework or use a recipe from another person changing some things but I never tried to build a complex ViewAction and I'm a bit lost.

推荐答案

我在您的问题下看到了您的评论.确实,我目前遇到了同样的问题(获得INJECT_EVENTS许可,我的所有变通办法都无法解决).我在半年前使用了该代码,它对我没有任何问题.

I have seen your comments under my question. Indeed I have faced the same problem at the moment (with INJECT_EVENTS permission and all my workarounds couldn't handle it). I used that code over half year ago and it worked for me without any problems.

我可以为您提出其他解决方案,但我不确定100%会奏效.因为我现在已经像超级快一样创建了它.以后我可能会有更多时间来查看它.

I can propose other solution for you but I am not 100% sure it will work. Because I have created it like super fast now. I might have more time to look at it later.

请尝试以下解决方案:

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

  1. Try to write your own GeneralSwipeAction. Look at constructor:

public GeneralSwipeAction(Swiper swiper, CoordinatesProvider startCoordinatesProvider, CoordinatesProvider endCoordinatesProvider, PrecisionDescriber precisionDescriber) {
    this.swiper = swiper;
    this.startCoordinatesProvider = startCoordinatesProvider;
    this.endCoordinatesProvider = endCoordinatesProvider;
    this.precisionDescriber = precisionDescriber;
}

因此,起点/终点的x,y位置是通过CoordinatesProvider类发送的.它是一个返回浮点数数组的接口.数组中的第一个浮点表示x,第二个浮点表示y.

So position of x,y of start/end point are sent via CoordinatesProvider class. And it is an interface that returns array of floats. First float in array represent x and second one represent y.

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

  1. Create your own class implementing Coordinates provider:

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

  • 使用此CustomisableCoordinatesProvider来实现执行拖动的自定义ViewAction:

  • Implement your custom ViewAction that performs drag with usage of this CustomisableCoordinatesProvider:

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

  • 并尝试像这样使用它:

  • And try to use it like this:

    onView(withId(R.id.test_player)).perform(drag(0, 100, 0, 100));
    

  • 我还没有测试过.但这可能会朝正确的方向工作或对您有所帮助.试试看,告诉我它是否有效,我自己很好奇:)

    I haven't tested it. But it might work or help you by pointing to right direction. Try it and tell me if it works, I am curious myself :)

    这篇关于Android Espresso,如何执行onLongClick和slideDown Continue?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆