Reputation: 648
Problem:
I built minesweeper and 350ms is too much to trigger the longPress event, I need more speed. I need implement time consider for GestureDetector, i need 200ms for detect long press event.
How my system build:
Every button use onTap and LongPress event.
My test:
I try to use this package: XGestureDetector
But it works bad because in different device not works.
I had seen but the onTap event does not work this way: StackOverFlow Answer
I need a method to solve my problem.
Upvotes: 3
Views: 7546
Reputation: 66
I've sometimes had some issues with GestureDetector
, so here's an alternate solution that uses a Listener
.
class CustomHoldListener extends StatefulWidget {
const CustomHoldListener({
this.holdDuration = const Duration(milliseconds: 350),
this.onTap,
this.onHold,
super.key,
});
final Duration holdDuration;
final VoidCallback? onTap;
final VoidCallback? onHold;
@override
State<CustomHoldListener> createState() => _CustomHoldListenerState();
}
class _CustomHoldListenerState extends State<CustomHoldListener> {
Duration? lastPointerDownTime;
@override
Widget build(BuildContext context) {
return Listener(
onPointerDown: (event) {
lastPointerDownTime = event.timeStamp;
},
onPointerUp: (event) {
if (lastPointerDownTime != null) {
if (event.timeStamp - lastPointerDownTime! > widget.holdDuration) {
widget.onHold?.call();
return;
}
}
widget.onTap?.call();
},
);
}
}
Upvotes: 1
Reputation: 648
Using @salihgueler answer, I found the solution:
class MyWidget extends StatefulWidget {
const MyWidget({Key? key}) : super(key: key);
@override
_MyWidgetState createState() => _MyWidgetState();
}
class _MyWidgetState extends State<MyWidget> {
late Timer _timer;
bool isLongPressed = false;
void _startOperation() {
_timer = Timer(const Duration(milliseconds: 200), () {
print('LongPress Event');
isLongPressed= true;
});
}
@override
Widget build(BuildContext context) {
return GestureDetector(
onTapDown: (_) {
_startOperation();
},
onTapUp: (_) {
_timer.cancel();
if(!isLongPressed)
{
print("Is a onTap event");
}
else
{
isLongPressed = false;
}
},
child: Text(
'Hello, World!',
style: Theme.of(context).textTheme.headline4,
),
);
}
}
Upvotes: 0
Reputation: 3632
There are multiple ways of doing it. I will show you something that I came up with that can help you start out with.
It starts a timer on each tap to the child and cancels it when you take your hand off. It takes advantage of onTapDown and onTapUp from GestureDetector, a widget that you are familiar from Flutter ecosystem.
class MyWidget extends StatefulWidget {
const MyWidget({Key? key}) : super(key: key);
@override
_MyWidgetState createState() => _MyWidgetState();
}
class _MyWidgetState extends State<MyWidget> {
late Timer _timer;
void _startOperation() {
_timer = Timer(const Duration(milliseconds: 200), () {
print('Do something after delay');
});
}
@override
void dispose() {
_timer.cancel();
super.dispose();
}
@override
Widget build(BuildContext context) {
return GestureDetector(
onTapDown: (_) {
_startOperation();
},
onTapUp: (_) {
_timer.cancel();
},
child: Text(
'Hello, World!',
style: Theme.of(context).textTheme.headline4,
),
);
}
}
Upvotes: 2