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

JavaFX是否支持触屏滑动滚动?求实现方案及示例代码

JavaFX 触屏惯性滚动(Fling)实现方案

核心结论

JavaFX 内置的 ListView、TreeView、TableView 等控件默认不支持快速滑动后的惯性滚动(Fling)手势,需要通过监听触摸事件结合动画手动实现,或使用第三方扩展库。

手动实现示例(以 ListView 为例)

通过监听触摸事件计算滑动速度,在手指释放后启动减速动画驱动控件滚动,是最直接的实现方式:

import javafx.animation.Animation;
import javafx.animation.KeyFrame;
import javafx.animation.Timeline;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.ListView;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
import javafx.util.Duration;

public class FlingListViewDemo extends Application {
    private Timeline flingTimeline;
    private double lastTouchY;
    private double scrollVelocity;
    // 可调整参数,控制滚动手感
    private static final double DECELERATION_RATE = 0.92;
    private static final double MIN_VELOCITY_THRESHOLD = 0.15;

    @Override
    public void start(Stage stage) {
        ListView<String> listView = new ListView<>();
        // 填充测试数据
        for (int i = 0; i < 100; i++) {
            listView.getItems().add("列表项 " + i);
        }

        // 触摸按下:记录初始位置,终止现有惯性动画
        listView.setOnTouchPressed(e -> {
            lastTouchY = e.getTouchPoint().getY();
            if (flingTimeline != null && flingTimeline.getStatus() == Animation.Status.RUNNING) {
                flingTimeline.stop();
            }
        });

        // 触摸拖动:计算实时滑动速度
        listView.setOnTouchMoved(e -> {
            double currentY = e.getTouchPoint().getY();
            scrollVelocity = lastTouchY - currentY;
            lastTouchY = currentY;
        });

        // 触摸释放:启动惯性滚动动画
        listView.setOnTouchReleased(e -> {
            flingTimeline = new Timeline(new KeyFrame(Duration.millis(16), event -> {
                if (Math.abs(scrollVelocity) < MIN_VELOCITY_THRESHOLD) {
                    flingTimeline.stop();
                    return;
                }
                // 驱动列表滚动
                listView.scrollBy(scrollVelocity);
                // 逐步减速
                scrollVelocity *= DECELERATION_RATE;
            }));
            flingTimeline.setCycleCount(Animation.INDEFINITE);
            flingTimeline.play();
        });

        VBox root = new VBox(listView);
        Scene scene = new Scene(root, 300, 500);
        stage.setTitle("触屏惯性滚动示例");
        stage.setScene(scene);
        stage.show();
    }

    public static void main(String[] args) {
        launch(args);
    }
}

关键细节

  • 触摸按下时终止现有动画,避免多个惯性效果冲突
  • 拖动过程中通过前后触摸点的Y轴差值计算滚动速度
  • 释放后启动循环动画,每帧根据速度滚动并减速,直到速度低于阈值停止
  • 调整DECELERATION_RATE(减速系数)和MIN_VELOCITY_THRESHOLD(停止阈值)可适配不同的滚动手感

替代方案

如果不想手动实现,可考虑以下Java生态方案:

  • ControlsFX:JavaFX官方推荐的扩展库,部分增强控件内置了触屏手势优化,可查看其最新版本的ListView/TableView扩展是否支持惯性滚动
  • Gluon Mobile:专为跨平台移动触屏应用设计的JavaFX框架,内置了完整的触屏手势支持(包括惯性滚动),适合移动端场景
  • SwingX(可选):若可切换到Swing,SwingX库的JXList控件原生支持惯性滚动,但Swing的触屏体验不如JavaFX

内容的提问来源于stack exchange,提问作者EQvan

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 09:33:43