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

Flutter中如何获取手指滑动速度并设置Future.delayed时长?

获取滑动速度并动态设置Future.delayed的Duration

问题描述

现有一段Flutter代码可实现红色容器跟随手指拖动移动,功能正常:

import 'package:flutter/material.dart';

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

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

class _TestState extends State<Test> {
  late Offset offsetAll = const Offset(0, 0);
  
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: GestureDetector(
          onPanUpdate: (t){
            offsetAll += t.delta;
            setState(() {});
          },
          child: Transform.translate(
            offset: offsetAll,
            child: Container(
              color: Colors.red,
              width: 100,
              height: 100,
            ),
          ),
        ),
      ),
    );
  }
}

需求是:获取手指滑动的当前速度(区分快慢),并将该速度值用于动态设置Future.delayed的Duration参数,请问是否可行?

实现方案

完全可行。Flutter的GestureDetector在onPanUpdate回调中提供的GestureDetails对象包含velocity属性,可直接获取当前滑动速度,再根据速度值映射到对应的Duration即可。

具体实现步骤

  1. 添加变量存储当前滑动速度和计算后的延迟时长
  2. 在onPanUpdate中实时获取滑动速度,计算对应的Duration
  3. 使用动态计算的Duration调用Future.delayed

修改后的完整代码

import 'package:flutter/material.dart';

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

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

class _TestState extends State<Test> {
  late Offset offsetAll = const Offset(0, 0);
  Velocity? _currentVelocity;
  Duration _delayDuration = const Duration(milliseconds: 500); // 默认延迟

  // 根据滑动速度计算延迟时长
  void _calculateDelayFromSpeed(Velocity velocity) {
    // 获取滑动的合速度(像素/秒)
    double speed = velocity.pixelsPerSecond.distance;
    
    // 速度越快,延迟越短;速度越慢,延迟越长
    if (speed > 600) {
      _delayDuration = const Duration(milliseconds: 100);
    } else if (speed > 300) {
      _delayDuration = const Duration(milliseconds: 300);
    } else {
      _delayDuration = const Duration(milliseconds: 500);
    }

    // 也可以用线性映射实现更平滑的过渡:比如速度0对应1000ms,速度1000对应100ms
    // double mappedMs = 1000 - (speed / 1000) * 900;
    // _delayDuration = Duration(milliseconds: mappedMs.clamp(100, 1000).toInt());
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: GestureDetector(
          onPanUpdate: (details) {
            offsetAll += details.delta;
            _currentVelocity = details.velocity;
            _calculateDelayFromSpeed(_currentVelocity!);
            setState(() {});

            // 使用动态计算的Duration调用Future.delayed
            Future.delayed(_delayDuration, () {
              // 这里写延迟后的逻辑
              print("延迟${_delayDuration.inMilliseconds}ms后执行");
            });
          },
          child: Transform.translate(
            offset: offsetAll,
            child: Container(
              color: Colors.red,
              width: 100,
              height: 100,
            ),
          ),
        ),
      ),
    );
  }
}

关键说明

  • details.velocity返回Velocity对象,其中pixelsPerSecond表示每秒滑动的像素偏移,通过distance方法可获取合速度大小
  • 可根据需求调整速度区间和对应的延迟时长,也可以用线性映射实现更平滑的过渡效果
  • 若需要在手指滑动结束后执行延迟逻辑,可将Future.delayed移至onPanEnd回调中,该回调的DragEndDetails同样包含velocity属性

内容的提问来源于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:10:39