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

Flutter中如何让组件沿用户滑动的正确方向持续移动?

解决Flutter滑动结束后容器沿正确方向持续移动的问题

你的问题核心是没有利用滑动结束时的真实速度方向,而是硬编码了dx++和dy++,导致只能朝固定方向移动。要实现沿用户滑动的正确方向持续移动,需要借助DragEndDetails提供的速度向量来计算后续的偏移量,同时可以加入减速逻辑让运动更符合物理直觉。

修改后的完整代码

import 'dart:async';
import 'package:flutter/material.dart';

class Test extends StatefulWidget {
  const Test({Key? key}) : super(key: key);

  @override
  State<Test> createState() => _TestState();
}

class _TestState extends State<Test> {
  Offset myOffset = const Offset(0, 0);
  Timer? _moveTimer;
  Offset _currentVelocity = Offset.zero;
  // 减速因子,值越小减速越快,范围0-1
  final double _deceleration = 0.95;
  // 最小速度阈值,低于此值停止运动
  final double _minVelocity = 2;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: GestureDetector(
          onPanUpdate: (details) {
            // 滑动过程中更新容器位置
            setState(() {
              myOffset += details.delta;
            });
            // 如果之前的运动还在进行,停止它
            _moveTimer?.cancel();
          },
          onPanEnd: (details) {
            // 获取滑动结束时的速度(每秒移动的像素)
            _currentVelocity = details.velocity.pixelsPerSecond;
            // 启动持续移动的定时器
            _moveTimer?.cancel();
            _moveTimer = Timer.periodic(const Duration(milliseconds: 16), (_) {
              setState(() {
                // 计算本次定时器回调的位移增量(16ms约为60帧的间隔)
                final delta = _currentVelocity * 0.016;
                myOffset += delta;
                // 应用减速,让速度逐渐减小
                _currentVelocity *= _deceleration;
              });
              // 当速度小于阈值时,停止定时器
              if (_currentVelocity.distance < _minVelocity) {
                _moveTimer?.cancel();
                _moveTimer = null;
              }
            });
          },
          child: Transform.translate(
            offset: myOffset,
            child: Container(
              color: Colors.red,
              width: 100,
              height: 100,
            ),
          ),
        ),
      ),
    );
  }

  @override
  void dispose() {
    // 页面销毁时取消定时器,避免内存泄漏
    _moveTimer?.cancel();
    super.dispose();
  }
}

关键修改点说明

  1. 利用滑动速度向量:
    • details.velocity.pixelsPerSecond直接给出了滑动结束时的速度方向和大小,这是实现正确方向移动的核心。
  2. 加入减速逻辑:
    • 通过_deceleration减速因子让速度逐渐衰减,模拟真实世界的滑动惯性,同时设置_minVelocity阈值,当速度足够小时停止运动。
  3. 优化定时器间隔:
    • 使用16ms的间隔(接近屏幕60帧的刷新频率),让动画更流畅。
  4. 滑动过程中停止惯性运动:
    • 在onPanUpdate中取消之前的定时器,避免用户再次滑动时出现冲突的运动状态。
  5. 内存泄漏防护:
    • 在dispose方法中取消定时器,确保页面销毁时资源被正确释放。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.02 15:30:21