You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.22 08:19:19