Appium中swipe已弃用,如何实现水平滑动?TouchActions报错求助
解决Appium中swipe弃用后的水平滑动及ClassCastException问题
先回答你的第一个问题:swipe方法弃用后的替代方案
Appium官方已经弃用了旧的swipe方法,现在主流有两种可靠的实现方式:Appium原生的TouchAction(适用于Appium 1.x,2.x中已标记为Deprecated)和W3C标准的PointerInput+Sequence(Appium 2.x官方推荐)。下面我会结合你的报错问题一起说明。
解决你的第二个问题:ClassCastException错误
你代码里用的TouchActions(复数)是Selenium旧版的触摸操作类,它要求Driver实现HasTouchScreen接口,但新版Appium的AndroidDriver已经不再实现这个接口了,这就是抛出类型转换异常的原因。
正确的做法是使用Appium自己的TouchAction类(单数,包路径是io.appium.java_client.TouchAction),而不是Selenium的org.openqa.selenium.interactions.TouchActions。
修正后的TouchAction实现水平滑动代码:
首先导入正确的依赖类:
import io.appium.java_client.TouchAction; import io.appium.java_client.touch.offset.PointOption; import org.openqa.selenium.Dimension;
然后修改你的Add_Feed方法(优化为通用水平滑动,避免硬编码坐标):
private static void Add_Feed() throws InterruptedException { // 获取屏幕尺寸,适配不同分辨率的设备 Dimension screenSize = driver.manage().window().getSize(); int startX = (int) (screenSize.width * 0.8); // 从屏幕右侧80%位置开始 int startY = screenSize.height / 2; // 垂直居中位置 int endX = (int) (screenSize.width * 0.2); // 滑动到屏幕左侧20%位置 int endY = startY; // Y坐标保持不变,实现纯水平滑动 // 使用Appium专属的TouchAction类 TouchAction action = new TouchAction(driver); action.press(PointOption.point(startX, startY)) .waitAction() // 可选添加短暂等待,模拟真实触摸的按压动作 .moveTo(PointOption.point(endX, endY)) .release() // 必须调用release才能完成完整的滑动动作 .perform(); // 建议把Thread.sleep替换为显式等待,测试稳定性会更高 // WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(3)); // wait.until(ExpectedConditions.visibilityOfElementLocated(By.yourLocator())); }
Appium 2.x推荐的新方案:PointerInput+Sequence
由于TouchAction在Appium 2.x中已被标记为过时,官方更推荐使用符合W3C标准的PointerInput和Sequence来实现触摸操作,兼容性更强,也更贴近真实用户的触摸行为。示例代码如下:
import org.openqa.selenium.Dimension; import org.openqa.selenium.interactions.PointerInput; import org.openqa.selenium.interactions.Sequence; import java.time.Duration; import java.util.Arrays; private static void horizontalSwipe() { // 创建触摸输入源,模拟手指操作 PointerInput finger = new PointerInput(PointerInput.Kind.TOUCH, "primary-finger"); // 创建动作序列,用来编排触摸的完整流程 Sequence swipeSequence = new Sequence(finger, 1); // 计算滑动的起始和结束坐标 Dimension screenSize = driver.manage().window().getSize(); int startX = (int) (screenSize.width * 0.8); int startY = screenSize.height / 2; int endX = (int) (screenSize.width * 0.2); int endY = startY; // 构建完整的滑动动作链:定位到起始点 → 按下 → 滑动到目标点 → 松开 swipeSequence.addAction( finger.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), startX, startY) ); swipeSequence.addAction( finger.createPointerDown(PointerInput.MouseButton.LEFT.asArg()) ); swipeSequence.addAction( finger.createPointerMove(Duration.ofMillis(300), PointerInput.Origin.viewport(), endX, endY) ); swipeSequence.addAction( finger.createPointerUp(PointerInput.MouseButton.LEFT.asArg()) ); // 执行这个动作序列 driver.perform(Arrays.asList(swipeSequence)); }
额外小贴士
- 尽量避免硬编码坐标,通过屏幕尺寸比例计算能让你的测试用例适配不同分辨率的设备。
- 不要依赖
Thread.sleep(),改用显式等待等待滑动后的目标元素出现,这样测试会更稳定可靠。
内容的提问来源于stack exchange,提问作者Amni Roy
相关产品推荐
相关产品推荐

