我定义为滑动,但它字面的意思又不是,事件的形式类似于小时候拿着一块石头片,朝水面飞过去,如果你手法可以那么就是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);
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; }
首先判断x坐标是否为0,如果为0,定义初始点的x坐标为控件的中心点的横坐标。如果x的坐标小于1,说明坐标为相对坐标,用百分比来求值,此时就要与宽度做乘积运算得到具体值。如果上面2种情况都不符合,那就是具体坐标值,那就直接元素的x坐标值加上控件的边框左坐标值。最后根据传入的boolean值来判断是否做一个超出边界的验证。如果超出边界就跑出异常。y坐标的获取方式类似。最后得到坐标值并返回,回到execute方法中。
absStartPos = getDeviceAbsPos(start); absEndPos = getDeviceAbsPos(end);
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: " + 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);
执行swipe命令有2中命令格式
坐标又分为相对坐标百分比和绝对坐标两种方法。
原文地址:http://blog.csdn.net/itfootball/article/details/37929673