Android Espresso,如何执行onLongClick和slideDown Continue? [英] Android Espresso, How can I perform onLongClick and slideDown continued?
问题描述
我的意思是,我可以按顺序执行这两个动作,但是中间有一个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.
请尝试以下解决方案:
-
尝试编写自己的GeneralSwipeAction.看一下构造函数:
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.
-
创建自己的实现Coordinates提供程序的类:
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屋!