Flick

package io.appium.android.bootstrap.handler;

import com.android.uiautomator.core.UiDevice;
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 flick elements in the Android UI.
*
* Based on the element Id, flick that element.
*
*/
public class Flick extends CommandHandler { private Point calculateEndPoint(final Point start, final Integer xSpeed,
final Integer ySpeed) {
final UiDevice d = UiDevice.getInstance();
final Point end = new Point();
final double speedRatio = (double) xSpeed / ySpeed;
double xOff;
double yOff; final double value = Math.min(d.getDisplayHeight(), d.getDisplayWidth()); if (speedRatio < 1) {
yOff = value / 4;
xOff = value / 4 * speedRatio;
} else {
xOff = value / 4;
yOff = value / 4 / speedRatio;
} xOff = Integer.signum(xSpeed) * xOff;
yOff = Integer.signum(ySpeed) * yOff; end.x = start.x + xOff;
end.y = start.y + yOff;
return end;
} /*
* @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 {
Point start = new Point(0.5, 0.5);
Point end = new Point();
Double steps; final Hashtable<String, Object> params = command.params();
final UiDevice d = UiDevice.getInstance(); if (command.isElementCommand()) {
AndroidElement el;
try {
el = command.getElement();
start = el.getAbsolutePosition(start);
final Integer xoffset = (Integer) params.get("xoffset");
final Integer yoffset = (Integer) params.get("yoffset");
final Integer speed = (Integer) params.get("speed"); steps = 1250.0 / speed + 1;
end.x = start.x + xoffset;
end.y = start.y + yoffset; } catch (final Exception e) {
return getErrorResult(e.getMessage());
}
} else {
try {
final Integer xSpeed = (Integer) params.get("xSpeed");
final Integer ySpeed = (Integer) params.get("ySpeed"); final Double speed = Math.min(1250.0,
Math.sqrt(xSpeed * xSpeed + ySpeed * ySpeed));
steps = 1250.0 / speed + 1; start = getDeviceAbsPos(start);
end = calculateEndPoint(start, xSpeed, ySpeed);
} catch (final InvalidCoordinatesException e) {
return getErrorResult(e.getMessage());
}
} steps = Math.abs(steps);
Logger.debug("Flicking from " + start.toString() + " to " + end.toString()
+ " with steps: " + steps.intValue());
final boolean res = d.swipe(start.x.intValue(), start.y.intValue(),
end.x.intValue(), end.y.intValue(), steps.intValue()); if (res) {
return getSuccessResult(res);
} else {
return getErrorResult("Flick did not complete successfully");
}
}
}

代码的步骤和swipe类似,并且终于调用的也是UiDevice.swipe方法,那么我们来看看究竟差别在什么地方。首先它也分控件和坐标,分别分析:

控件

首先将控件的中心点作为起始坐标,然后依据提供的參数xoffset和yoffset来获取位移数据,speed參数用来计算步骤。

steps = 1250.0 / speed + 1;
end.x = start.x + xoffset;
end.y = start.y + yoffset;

起始坐标加上位移就是结束坐标,这个steps的设置还是有点让人摸不着头脑的,我这个1250我且觉得是最大位移吧,speed代表每一步走的路程。用1250/speed得到使用多少步到结束点,再加上初始值的那个点就得到steps的值啦。至此起始点坐标、结束点坐标、步骤的值都设置完成。

坐标

严格来说,不能说成坐标,应该算坐标位移,由于才传入的參数事实上坐标系的速度xSpeed和ySpeed。x轴移动xSpeed距离,y轴移动ySpeed坐标。然后获取坐标值和steps值。

当中它用1250和位移的平方做了一次比較,取出最小值来计算steps。起始坐标点定位屏幕的中心点坐标。然后再调用end = calculateEndPoint(start, xSpeed, ySpeed);方法获取结束点坐标。

private Point calculateEndPoint(final Point start, final Integer xSpeed,
final Integer ySpeed) {
final UiDevice d = UiDevice.getInstance();
final Point end = new Point();
final double speedRatio = (double) xSpeed / ySpeed;
double xOff;
double yOff; final double value = Math.min(d.getDisplayHeight(), d.getDisplayWidth()); if (speedRatio < 1) {
yOff = value / 4;
xOff = value / 4 * speedRatio;
} else {
xOff = value / 4;
yOff = value / 4 / speedRatio;
} xOff = Integer.signum(xSpeed) * xOff;
yOff = Integer.signum(ySpeed) * yOff; end.x = start.x + xOff;
end.y = start.y + yOff;
return end;
}

首先计算位移比speedRatio(x的位移/y的位移),然后获取屏幕宽和高中最小的一个数复制给value.假设speedRatio<1,x的移动距离为value的值的1/4.y坐标为和x移动的距离是一样的。所以经过上面的计算得到的结束点的坐标和起始点组成的应该是正方型的对角线。

最后调用UiDevice.swipe和Swipe中是一样的啦。没什么特别的

总结

特别想知道1250代表的是什么。不然老认为还没理解这种方法的意思。哎

bootstrap之Flick的更多相关文章

  1. bootstrap之Click大事

    上一篇文章中谈到了bootstrap流程,本文开始把目光bootstrap它可以接受指令(从源代码视图的透视.因为appium该项目现在还处于不断更新,因此,一些指令已经实现.也许未来会实现一些.从视 ...

  2. Appium Android Bootstrap源码分析之命令解析执行

    通过上一篇文章<Appium Android Bootstrap源码分析之控件AndroidElement>我们知道了Appium从pc端发送过来的命令如果是控件相关的话,最终目标控件在b ...

  3. Appuim源码剖析(Bootstrap)

    Appuim源码剖析(Bootstrap) SkySeraph Jan. 26th 2017 Email:skyseraph00@163.com 更多精彩请直接访问SkySeraph个人站点:www. ...

  4. 手机自动化测试:appium源码分析之bootstrap三

    手机自动化测试:appium源码分析之bootstrap三   研究bootstrap源码,我们可以通过代码的结构,可以看出来appium的扩展思路和实现方式,从中可以添加我们自己要的功能,针对app ...

  5. 手机自动化测试:appium源码分析之bootstrap二

    手机自动化测试:appium源码分析之bootstrap二   在bootstrap项目中的io.appium.android.bootstrap.handler包中的类都是对应的指令类, priva ...

  6. 手机自动化测试:appium源码分析之bootstrap一

    手机自动化测试:appium源码分析之bootstrap一   前言: poptest是国内唯一一家培养测试开发工程师的培训机构,以学员能胜任自动化测试,性能测试,测试工具开发等工作为目标.popte ...

  7. 手机自动化测试:appium源码分析之bootstrap六

    手机自动化测试:appium源码分析之bootstrap六   poptest是国内唯一一家培养测试开发工程师的培训机构,以学员能胜任自动化测试,性能测试,测试工具开发等工作为目标.poptest测试 ...

  8. appium框架之bootstrap

    (闲来无事,做做测试..)最近弄了弄appium,感觉挺有意思,就深入研究了下. 看小弟这篇文章之前,先了解一下appium的架构,对你理解有好处,推荐下面这篇文章:testerhome appium ...

  9. 旺财速啃H5框架之Bootstrap(五)

    在上一篇<<旺财速啃H5框架之Bootstrap(四)>>做了基本的框架,<<旺财速啃H5框架之Bootstrap(二)>>篇里也大体认识了bootst ...

随机推荐

  1. 【解决方法】EasyUI DataGrid不显示滚动条时,没有数据的问题

    解决方法 于dataGrid例如,下面的代码被添加到的定义:  JavaScript Code  1 2 3 4 5 6 7 8 9 10 onLoadSuccess : function (data ...

  2. sql语句中BEGIN TRAN...COMMIT TRAN

    BEGIN TRAN标记事务開始  COMMIT TRAN 提交事务  一般把DML语句(select ,delete,update,insert语句)放在BEGIN TRAN...COMMIT TR ...

  3. WebBrowser如何获取提交的数据

    WebBrowser 其实是对 ActiveX 控件 SHDocVw 的封装,而这个SHDocVw的很多底层调用WebBrowser控件并没有提供实现,你这个应用需要直接操作 SHDoceVw 控件才 ...

  4. CppCon - Modern Template Metaprogramming 杂记

    2014年底才看到github和channel9上有CppCon2014的视频和资料,顿时激动不已.最近小生也一直在研习CppCon2014中令人兴奋的内容.这篇鄙文就是小生学习了<Modern ...

  5. hdu3599 War(最大流)

    转载请注明出处: http://www.cnblogs.com/fraud/          ——by fraud War Time Limit: 2000/1000 MS (Java/Others ...

  6. 子元素用margin-top 为什么反而作用在父元素上?对使用margin-top 的元素本身不起作用?

    在这个说明中,“collapsing margins”(折叠margin)的意思是:2个或以上盒模型之间(关系可以是相邻或嵌套)相邻的margin属性(这之间不能有非空内容.padding区域.bor ...

  7. 第二章IPC——IPC与开启多进程

    问题 一.IPC ①.什么是IPC  ②.为什么要有IPC 二.多进程 ①.如何开启多进程  ②.系统如何创建多进程 三.多进程引发的问题 问:私有进程(利用":+进程名")能否共 ...

  8. dedecms 财付通接口

    用织梦做了个旅游网站,网址:http://www.redtourism.cn/ 客户要求财付通支付,上网找了下 不是要买就是要钱,只有自己写了. 代码: <?phpif(!defined('DE ...

  9. DIRECTORY_SEPARATOR的作用

    IRECTORY_SEPARATOR是php的内部常量,用于显示系统分隔符的命令,不需要任何定义与包含即可直接使用. 在windows下路径分隔符是/(当然/在部分系统上也是可以正常运行的),在lin ...

  10. Pie(hdu 1969 二分查找)

    Pie Time Limit: 5000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submiss ...