class AppMultipleTap extends StatefulWidget {
final Widget child;
final VoidCallback onMultipleTap;
final int taps;
final Duration duration;
const AppMultipleTap({
super.key,
required this.child,
required this.onMultipleTap,
/// feel free to override these values
this.taps = 3,
this.duration = const Duration(milliseconds: 600),
});
@override
State<AppMultipleTap> createState() => _AppMultipleTapState();
}
class _AppMultipleTapState extends State<AppMultipleTap> {
/// in _count we store current number of taps
int _count = 0;
Timer? _timer;
@override
Widget build(BuildContext context) {
return Listener(
onPointerDown: (_) {
if (_timer == null) _startTimer();
_count++;
},
child: widget.child,
);
}
void _startTimer() {
_timer = Timer(widget.duration, () {
/// you can change this condition to ==, if you need 100% match
if (_count >= widget.taps) {
widget.onMultipleTap.call();
}
_timer = null;
_count = 0;
});
}
}
你可以这样使用它:
@override
Widget build(BuildContext context) {
return AppMultipleTap(
onMultipleTap: /// Do some action
// Variables in the state class
var startTap = timeNow;
var consecutiveTaps = 0;
static const int serialTaps = 4;
static const int tapDurationInMs = 1000;
static int get timeNow => DateTime.now().millisecondsSinceEpoch;
// Build method
GestureDetector(
onTap: () {
final now = timeNow;
final userExceededTapDuration = now - startTap > tapDurationInMs;
if (userExceededTapDuration) {
consecutiveTaps = 0;
startTap = now;
}
consecutiveTaps++;
if (consecutiveTaps == serialTaps) {
// widget.onTap();
}
},
);
6条答案
按热度按时间vyu0f0g11#
我对这个有点懒,实际上并不难
qq24tv8q2#
我尝试了这里提到的方法,但它对我不起作用。GestureDetector onTap仅被调用一次,而与点击次数无关。可能有些东西已经改变了Flutter(我在测试频道)。然而,我深入研究了flutter的源代码,并得出了解决方案(https://api.flutter.dev/flutter/gestures/SerialTapGestureRecognizer-class.html):
pbossiut3#
我采取了一种不同的方法。我设置了一个Timer,而不是必须比较时间戳,它将重置被点击的状态。但每次有一个水龙头,旧计时器被取消。
eimct9ow4#
我已经尝试过这种方法,减少超时,并与两次和三次点击
bbuxkriu5#
相关解决方案。这是一个灵活的可重用的多点点击小部件,它基于报告原始指针事件的监听器小部件:
你可以这样使用它:
cxfofazt6#
我喜欢这种简单的方法,没有那么多嵌套的if块。