Android 浓缩咖啡:如何进行自定义刷卡,例如:swipeTop或swipeBottom

Android 浓缩咖啡:如何进行自定义刷卡,例如:swipeTop或swipeBottom,android,android-espresso,ui-testing,Android,Android Espresso,Ui Testing,到目前为止,我们可以做到: 游泳池 泳镜 游泳 游泳池 我们怎么能用expresso(一路滑到顶部)或swipeBottom(一路滑到底部)呢。如果这些方法已经存在,请给我一个例子。我认为可以通过执行滑动来编写复杂的ViewActions public static ViewAction swipeToTop() { return new MySwipeAction(Swipe.FAST, GeneralLocation.CENTER, new Coo

到目前为止,我们可以做到:

  • 游泳池
  • 泳镜
  • 游泳
  • 游泳池

我们怎么能用expresso(一路滑到顶部)或swipeBottom(一路滑到底部)呢。如果这些方法已经存在,请给我一个例子。

我认为可以通过执行滑动来编写复杂的
ViewActions

public static ViewAction swipeToTop() {
    return new MySwipeAction(Swipe.FAST,
        GeneralLocation.CENTER,
        new CoordinatesProvider() {
            @Override
            public float[] calculateCoordinates(View view) {
                float[] coordinates =  GeneralLocation.CENTER.calculateCoordinates(view);
                coordinates[1] = 0;
                return coordinates;
            }
    }, Press.FINGER);
}


public static ViewAction swipeToBottom() {
    return new MySwipeAction(Swipe.FAST,
        GeneralLocation.CENTER,
        new CoordinatesProvider() {
            @Override
            public float[] calculateCoordinates(View view) {
                float[] coordinates = GeneralLocation.CENTER.calculateCoordinates(view);
                coordinates[1] = view.getContext().getResources().getDisplayMetrics().heightPixels;
                return coordinates;
            }
    }, Press.FINGER);
}
我的行动可能是这样的:

public class MySwipeAction implements ViewAction {
    public MySwipeAction(Swiper swiper, CoordinatesProvider startCoordProvide, CoordinatesProvider endCoordProvide, PrecisionDescriber precDesc) { 
           // store here in class variables to use in perform
           ...
    }

    @Override public Matcher<View> getConstraints() {...}

    @Override public String getDescription() {...}

    @Override
    public void perform(UiController uiController, View view) {
        ...
        float[] startCoord = startCoordProvide.calculateCoordinates(view);
        float[] finalCoord = endCoordProvide.calculateCoordinates(view);
        float[] precision =  precDesc.describePrecision();

        Swiper.Status status = Swiper.Status.FAILURE;

        // you could try this for several times until Swiper.Status is achieved or try count is reached
        try {
            status = m_swiper.sendSwipe(uiController, startCoord, finalCoord, precision);
        } catch (RuntimeException re) {
            ...
        }

        // ensures that the swipe has been run.
        uiController.loopMainThreadForAtLeast(ViewConfiguration.getPressedStateDuration());
    }
}
Espresso.onView(ViewMatchers.withId(R.id.recyclerView)).perform(ViewActions.swipeUp())
public类MySwipeAction实现ViewAction{
公共活动(Swiper-Swiper、CoordinateProvider StartOrdProvider、CoordinateProvider EndCoordProvider、PrecisionDescriber Predesc){
//将要在执行中使用的变量存储在类中
...
}
@重写公共匹配器getConstraints(){…}
@重写公共字符串getDescription(){…}
@凌驾
公共作废执行(UiController UiController,视图){
...
float[]startCord=startCordProvider.Calculate坐标(视图);
float[]finalcord=endCoordProvider.calculateCoordinates(视图);
float[]精度=predesc.describePrecision();
Swiper.Status Status=Swiper.Status.FAILURE;
//您可以尝试多次,直到达到Swiper.Status或try count
试一试{
状态=m_swiper.sendSwipe(uiController、startOrd、finalOrd、precision);
}捕获(运行时异常re){
...
}
//确保已运行刷卡。
uiController.loopMainThreadForAtLeast(ViewConfiguration.getPressedStateDuration());
}
}

我希望这能对您有所帮助。

您有没有尝试过像这样的
常规WipeAction

private static ViewAction swipeFromTopToBottom() {
    return new GeneralSwipeAction(Swipe.FAST, GeneralLocation.TOP_CENTER,
            GeneralLocation.BOTTOM_CENTER, Press.FINGER);
}
可能您必须为第二个和/或第三个参数提供自定义实现,正如Anna已经提到的:

new CoordinatesProvider() {
    @Override
    public float[] calculateCoordinates(View view) {
        float[] coordinates =  GeneralLocation.CENTER.calculateCoordinates(view);
        coordinates[1] = 0;
        return coordinates;
    }
}
@testsingh 我认为没有现成的方法来做“swipeTop”或“swipeBottom” 下面的循环可能是对我来说最简单(最愚蠢)的方法XDDD

//swipeUp 100次,swipeDown反之亦然

for(int i=0;i<=100;i++){
  onView(withText("label")).perform(swipeUp());
}

for(int i=0;i例如,如果您在应用程序中使用recyclerView,您可以使用如下内容:

public class MySwipeAction implements ViewAction {
    public MySwipeAction(Swiper swiper, CoordinatesProvider startCoordProvide, CoordinatesProvider endCoordProvide, PrecisionDescriber precDesc) { 
           // store here in class variables to use in perform
           ...
    }

    @Override public Matcher<View> getConstraints() {...}

    @Override public String getDescription() {...}

    @Override
    public void perform(UiController uiController, View view) {
        ...
        float[] startCoord = startCoordProvide.calculateCoordinates(view);
        float[] finalCoord = endCoordProvide.calculateCoordinates(view);
        float[] precision =  precDesc.describePrecision();

        Swiper.Status status = Swiper.Status.FAILURE;

        // you could try this for several times until Swiper.Status is achieved or try count is reached
        try {
            status = m_swiper.sendSwipe(uiController, startCoord, finalCoord, precision);
        } catch (RuntimeException re) {
            ...
        }

        // ensures that the swipe has been run.
        uiController.loopMainThreadForAtLeast(ViewConfiguration.getPressedStateDuration());
    }
}
Espresso.onView(ViewMatchers.withId(R.id.recyclerView)).perform(ViewActions.swipeUp())


我知道我参加聚会迟到了,但经过一番欺骗之后,我终于找到了一种可以从上到下、从左到右滑动的东西——不需要任何资源id

我之所以需要它是为了一个动态填充的视图,其中所有内容都是完全不明确的。使用下面的方法,我可以一直滚动到底部,甚至可以更改延迟以只向下滚动一页

static void swiper(int start, int end, int delay) {
    long downTime = SystemClock.uptimeMillis();
    long eventTime = SystemClock.uptimeMillis();
    Instrumentation inst = getInstrumentation();

    MotionEvent event = MotionEvent.obtain(downTime, eventTime, MotionEvent.ACTION_DOWN, 500, start, 0);
    inst.sendPointerSync(event);
    eventTime = SystemClock.uptimeMillis() + delay;
    event = MotionEvent.obtain(downTime, eventTime, MotionEvent.ACTION_MOVE, 500, end, 0);
    inst.sendPointerSync(event);
    event = MotionEvent.obtain(downTime, eventTime, MotionEvent.ACTION_UP, 500, end, 0);
    inst.sendPointerSync(event);
    SystemClock.sleep(2000); //The wait is important to scroll
}
我不需要从左到右等,所以我硬编码的500在那里(500是x轴)

打电话给他们我做到了我做到了-

 // This swipes all the way to the bottom of the screen
public static void swipeToBottom(){
    swiper(1000, 100, 0);
}

// This scrolls down one page at a time
public static void scrollSlowlyDown(){
    swiper(775, 100, 100);
}

// This swipes to the top
public static void swipeToTop(){
    swiper(100, 1000, 0);
}

// This scrolls up one page at a time
public static void scrollSlowlyUp(){
    swiper(100, 775, 100);
}
我希望这能帮助那些偶然发现这个的人。

/p>//向上滑动

for(int i=0;i<=3;i++){
    onView(allOf(withId(R.id.recycler_view),isDisplayed())).perform(actionOnItemAtPosition(4, swipeUp()));
}

for(int i=0;iis注释和点太多…如果您有“full”请展示您的代码示例。许多人不知道他们可以在您的“…”中输入什么,我同意。排除代码中使用的变量定义和赋值是令人困惑的。如果它使代码更难阅读,那么节省几行代码就不值得了。不确定我为什么会被否决-不幸的是,在targetSdk 26中,这非常有效,在Android 7上运行时,会抛出一个:java.lang.SecurityException:注入到另一个应用程序需要INJECT_EVENTS权限,该权限仅授予系统应用程序。