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即可。
具体实现步骤
- 添加变量存储当前滑动速度和计算后的延迟时长
- 在
onPanUpdate中实时获取滑动速度,计算对应的Duration - 使用动态计算的
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
相关产品推荐
相关产品推荐

