按边界/坐标单击

32

我知道Espresso可以像UiAutomator一样通过边界进行点击(使用x和y坐标)。我已经阅读了文档,但似乎找不到它。如果有帮助,请谢谢。

编辑
我找到了这个链接,但没有示例如何使用它,我的主要关注点是UiController是什么或者如何使用它。

3个回答

61

Espresso有GeneralClickAction,它是ViewActions click()doubleClick()longClick()的基本实现。

GeneralClickAction 的构造函数将 CoordinatesProvider 作为第二个参数。 因此,基本思路是创建一个静态的 ViewAction getter,提供自定义的 CoordinatesProvider。像这样:

public static ViewAction clickXY(final int x, final int y){
    return new GeneralClickAction(
        Tap.SINGLE,
        new CoordinatesProvider() {
            @Override
            public float[] calculateCoordinates(View view) {

               final int[] screenPos = new int[2];
               view.getLocationOnScreen(screenPos);

               final float screenX = screenPos[0] + x;
               final float screenY = screenPos[1] + y;
               float[] coordinates = {screenX, screenY};

               return coordinates;
            }
        },
        Press.FINGER);
}

使用 Espresso 时的一般建议:不要寻找文档(实际上几乎没有),而是查看源代码。Espresso 是开源的,源代码本身真的很优秀。


谢谢你的回答!等我有机会测试一下,我会接受它的。 - Chad Bingham
1
抱歉晚了才请求帮助,但是这个程序不起作用。我没有收到任何错误信息,但是它也没有在任何地方起作用。我是否有什么地方理解不正确? - Chad Bingham
需要记住的一件事是,x和y是相对于视图左侧/顶部的坐标,而不是屏幕左侧/顶部的坐标。但是我现在想不到更多的了。我们经常使用这种自定义CoordinatesProviders,并且迄今为止没有遇到任何问题。您还可以尝试将screenX/screenY记录到logcat中,看看这些值是否有意义。 - haffax
3
您正在执行的视图。onView(..)。perform(clickXY(10,20)); 该视图由传递给onView的匹配器匹配。 - haffax
1
@haffax 我想使用屏幕绝对坐标(例如,屏幕的0,0点)。我应该在 onView(...) 中输入什么?我尝试了 onView(isRoot()),但没有匹配项。注意:我当前正在前台显示对话框。 - kiruwka
显示剩余2条评论

15

虽然这种方法已过时,但有效的答案帮助了我。 现在您必须指定inputDevice(例如InputDevice.SOURCE_MOUSE)和buttonState (例如MotionEvent.BUTTON_PRIMARY)。

Kotlin示例:

companion object {
    fun clickIn(x: Int, y: Int): ViewAction {
        return GeneralClickAction(
                Tap.SINGLE,
                CoordinatesProvider { view ->
                    val screenPos = IntArray(2)
                    view?.getLocationOnScreen(screenPos)

                    val screenX = (screenPos[0] + x).toFloat()
                    val screenY = (screenPos[1] + y).toFloat()

                    floatArrayOf(screenX, screenY)
                },
                Press.FINGER,
                InputDevice.SOURCE_MOUSE,
                MotionEvent.BUTTON_PRIMARY)
    }
}

11

@haffax的回答很好并且有效。

不过,如果您想要点击View中可能会在不同屏幕上变化的某个特定部分,则根据百分比(或比例)进行点击可能会很有用,因为即使dp数字在所有屏幕上也可能不稳定。因此,我对它进行了简单的修改:

    public static ViewAction clickPercent(final float pctX, final float pctY){
    return new GeneralClickAction(
            Tap.SINGLE,
            new CoordinatesProvider() {
                @Override
                public float[] calculateCoordinates(View view) {

                    final int[] screenPos = new int[2];
                    view.getLocationOnScreen(screenPos);
                    int w = view.getWidth();
                    int h = view.getHeight();

                    float x = w * pctX;
                    float y = h * pctY;

                    final float screenX = screenPos[0] + x;
                    final float screenY = screenPos[1] + y;
                    float[] coordinates = {screenX, screenY};

                    return coordinates;
                }
            },
            Press.FINGER);
}

我想在这里分享它,以便其他人也能受益。


3
谢谢。如果有人使用这段代码,pctX和pctY的值范围为0到1。 - sat

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接