【问题标题】:Click by bounds / coordinates按边界/坐标单击
【发布时间】:2014-03-04 16:33:10
【问题描述】:

我知道 Espresso 可以通过 UiAutomator does 的方式点击边界。 (x 和 y 坐标)我已通读文档,但似乎找不到。任何帮助表示赞赏。谢谢

编辑
我找到了this link,但没有示例如何使用它,我主要关心的是UiController 是或如何使用它。

【问题讨论】:

    标签: android android-testing android-espresso


    【解决方案1】:

    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 是开源的,源代码本身质量非常好。

    【讨论】:

    • 感谢您的回答!当我有机会测试它时,我会接受它。
    • 很抱歉请求帮助晚了,但这不是点击。我没有收到任何错误,但它也没有点击任何地方。有什么我不明白的地方吗?
    • 要记住的一点是,x、y 是相对于视图左/上的坐标,而不是屏幕左/上的坐标。但除此之外,我现在想不出更多。我们经常使用这种自定义 CoordinatesProviders,到目前为止没有遇到任何问题。您还可以尝试将 screenX/screenY 记录到 logcat 中,看看这些值是否有意义。
    • 您正在执行它的视图。 onView(..).perform(clickXY(10, 20));由提供给 onView 的匹配器匹配的视图。
    • @haffax 我想使用屏幕绝对坐标(比如屏幕的 0,0)。我应该给onView(...) 写什么?我试过`onView(isRoot())。它失败了,没有匹配。注意:我目前正在前面显示对话框
    【解决方案2】:

    尽管该方法已被弃用,但有效答案对我有所帮助。 现在你必须指定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)
        }
    }
    

    【讨论】:

      【解决方案3】:

      @haffax 的回答很棒而且效果很好。

      但是,如果您想点击视图的某个部分,该部分可能会因屏幕而异,那么根据百分比(或比率)进行点击可能会很有用,因为即使 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);
      }
      

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

      【讨论】:

      • 谢谢。如果有人使用此代码,pctX 和 pctY 的值范围从 0 到 1。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-05-15
      • 2014-03-24
      • 1970-01-01
      • 1970-01-01
      • 2015-11-26
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多