zoukankan      html  css  js  c++  java
  • bootstrap之Swipe

    Swipe


    我定义为滑动,但它字面的意思又不是,事件的形式类似于小时候拿着一块石头片,朝水面飞过去,假设你手法能够那么就是swipe走的路线,假设你手法不行,接触水面的时候就没再飞起来那就会被人嘲笑的。


    package io.appium.android.bootstrap.handler;
    
    import com.android.uiautomator.core.UiDevice;
    import com.android.uiautomator.core.UiObjectNotFoundException;
    import io.appium.android.bootstrap.*;
    import io.appium.android.bootstrap.exceptions.InvalidCoordinatesException;
    import io.appium.android.bootstrap.utils.Point;
    import org.json.JSONException;
    
    import java.util.Hashtable;
    
    /**
     * This handler is used to swipe.
     * 
     */
    public class Swipe extends CommandHandler {
    
      /*
       * @param command The {@link AndroidCommand} used for this handler.
       * 
       * @return {@link AndroidCommandResult}
       * 
       * @throws JSONException
       * 
       * @see io.appium.android.bootstrap.CommandHandler#execute(io.appium.android.
       * bootstrap.AndroidCommand)
       */
      @Override
      public AndroidCommandResult execute(final AndroidCommand command)
          throws JSONException {
        final Hashtable<String, Object> params = command.params();
        final Point start = new Point(params.get("startX"), params.get("startY"));
        final Point end = new Point(params.get("endX"), params.get("endY"));
        final Integer steps = (Integer) params.get("steps");
        final UiDevice device = UiDevice.getInstance();
    
        Point absStartPos = new Point();
        Point absEndPos = new Point();
    
        if (command.isElementCommand()) {
          try {
            final AndroidElement el = command.getElement();
            absStartPos = el.getAbsolutePosition(start);
            absEndPos = el.getAbsolutePosition(end, false);
          } catch (final UiObjectNotFoundException e) {
            return getErrorResult(e.getMessage());
          } catch (final InvalidCoordinatesException e) {
            return getErrorResult(e.getMessage());
          } catch (final Exception e) { // handle NullPointerException
            return getErrorResult("Unknown error");
          }
        } else {
          try {
            absStartPos = getDeviceAbsPos(start);
            absEndPos = getDeviceAbsPos(end);
          } catch (final InvalidCoordinatesException e) {
            return getErrorResult(e.getMessage());
          }
        }
    
        Logger.debug("Swiping from " + absStartPos.toString() + " to "
            + absEndPos.toString() + " with steps: " + steps.toString());
        final boolean rv = device.swipe(absStartPos.x.intValue(),
            absStartPos.y.intValue(), absEndPos.x.intValue(),
            absEndPos.y.intValue(), steps);
        if (!rv) {
          return getErrorResult("The swipe did not complete successfully");
        }
        return getSuccessResult(rv);
      }
    }
    

    无论它怎样定义,先分析源代码最后再定义。


        final Hashtable<String, Object> params = command.params();
        final Point start = new Point(params.get("startX"), params.get("startY"));
        final Point end = new Point(params.get("endX"), params.get("endY"));
        final Integer steps = (Integer) params.get("steps");
        final UiDevice device = UiDevice.getInstance();
    
        Point absStartPos = new Point();
        Point absEndPos = new Point();
    


    首先从命令里取得參数,然后解析出所须要的3个变量:起始点start、终点end、步骤steps。然后获得设备对象,定义2个私有Point对象,以备后用。

    然后分条件处理,处理控件还是处理坐标。


    控件


            final AndroidElement el = command.getElement();
            absStartPos = el.getAbsolutePosition(start);
            absEndPos = el.getAbsolutePosition(end, false);

    首先获取控件对象,再通过getAbsolutePosition传入不同的參数获得在该控件上点击的起始点和结束点。


    public Point getAbsolutePosition(final Point point,
          final boolean boundsChecking) throws UiObjectNotFoundException,
          InvalidCoordinatesException {
        final Rect rect = el.getBounds();
        final Point pos = new Point();
        Logger.debug("Element bounds: " + rect.toShortString());
    
        if (point.x == 0) {
          pos.x = rect.width() * 0.5 + rect.left;
        } else if (point.x <= 1) {
          pos.x = rect.width() * point.x + rect.left;
        } else {
          pos.x = rect.left + point.x;
        }
        if (boundsChecking) {
          if (pos.x > rect.right || pos.x < rect.left) {
            throw new InvalidCoordinatesException("X coordinate ("
                + pos.x.toString() + " is outside of element rect: "
                + rect.toShortString());
          }
        }
    
        if (point.y == 0) {
          pos.y = rect.height() * 0.5 + rect.top;
        } else if (point.y <= 1) {
          pos.y = rect.height() * point.y + rect.top;
        } else {
          pos.y = rect.left + point.y;
        }
        if (boundsChecking) {
          if (pos.y > rect.bottom || pos.y < rect.top) {
            throw new InvalidCoordinatesException("Y coordinate ("
                + pos.y.toString() + " is outside of element rect: "
                + rect.toShortString());
          }
        }
    
        return pos;
      }

    上面的一大段代码,看起来非常复杂,事实上非常easy,业务非常容易理解,处理这样的点的时候就须要推断非常多东西。上面的代码首先分析x坐标然后分析y坐标。x和y坐标的推断和处理时一样的,所以我仅仅讲一下x坐标。

    首先推断x坐标是否为0,假设为0,定义初始点的x坐标为控件的中心点的横坐标。假设x的坐标小于1,说明坐标为相对坐标,用百分比来求值,此时就要与宽度做乘积运算得到详细值。假设上面2种情况都不符合,那就是详细坐标值,那就直接元素的x坐标值加上控件的边框左坐标值。最后依据传入的boolean值来推断是否做一个超出边界的验证。假设超出边界就跑出异常。y坐标的获取方式类似。最后得到坐标值并返回,回到execute方法中。


    坐标


    absStartPos = getDeviceAbsPos(start);
            absEndPos = getDeviceAbsPos(end);

    通过调用getDeviceAbsPos()方法得到坐标值来初始化之前声明的私有Point对象.


    protected static Point getDeviceAbsPos(final Point point)
          throws InvalidCoordinatesException {
        final UiDevice d = UiDevice.getInstance();
        final Point retPos = new Point(point); // copy inputed point
    
        final Double width = (double) d.getDisplayWidth();
        if (point.x < 1) {
          retPos.x = width * point.x;
        }
    
        if (retPos.x > width || retPos.x < 0) {
          throw new InvalidCoordinatesException("X coordinate ("
              + retPos.x.toString() + " is outside of screen  "
              + width.toString());
        }
    
        final Double height = (double) d.getDisplayHeight();
        if (point.y < 1) {
          retPos.y = height * point.y;
        }
    
        if (retPos.y > height || retPos.y < 0) {
          throw new InvalidCoordinatesException("Y coordinate ("
              + retPos.y.toString() + " is outside of screen height: "
              + height.toString());
        }
    
        return retPos;
      }

    类似于上面的方法,也是要先推断传过来的坐标值是否小于1,假设小于1,当作百分比来球坐标值。假设超出屏幕的范围抛出异常,最后返回坐标值回到execute方法。

    ===============================================================================================================================


    final boolean rv = device.swipe(absStartPos.x.intValue(),
            absStartPos.y.intValue(), absEndPos.x.intValue(),
            absEndPos.y.intValue(), steps);

    最后调用UiDevice.swipe方法来运行命令,推断是否运行成功。


    总结


    运行swipe命令有2中命令格式

    • 控件
    • 坐标

    坐标又分为相对坐标百分比和绝对坐标两种方法。















  • 相关阅读:
    UVA 10462 Is There A Second Way Left?(次小生成树&Prim&Kruskal)题解
    POJ 1679 The Unique MST (次小生成树)题解
    POJ 2373 Dividing the Path (单调队列优化DP)题解
    BZOJ 2709 迷宫花园
    BZOJ 1270 雷涛的小猫
    BZOJ 2834 回家的路
    BZOJ 2506 calc
    BZOJ 3124 直径
    BZOJ 4416 阶乘字符串
    BZOJ 3930 选数
  • 原文地址:https://www.cnblogs.com/hrhguanli/p/3869722.html
Copyright © 2011-2022 走看看