I have nested GestureDetetor
s but problem is that only the child GestureDetector
's onTap
is executed. I do not wish to override the child's onTap, rather, I want both the parent's and the child's onTap to execute. Here's my code:
GestureDetector(
onTap: () {
todo1();
},
child: GestureDetector(
onTap: () {
todo2();
},
child: Text("Nested Gesture")))
How do I change this to call both todo1()
and todo2()
onTap?
edit: the child is a re-usable custom widget that has its own implementation but is now being used by the parent which also has an implementation of its own in addition to its child
I made a quick custom gesture recognizer - it cancels the gesture only if user has moved too far from the initial tap point.
Usage example:
UniversalTapHandler(
onTap: () {
print("Tap 1");
},
child: UniversalTapHandler(
onTap: () {
print("Tap 2");
},
child: Text("Nested Gesture"),
)
)
Source code:
class UniversalTapHandler extends RawGestureDetector {
UniversalTapHandler({
@required GestureTapCallback onTap,
@required Widget child,
}):
super(
gestures: <Type, GestureRecognizerFactory>{
_UniversalPointerHandler: GestureRecognizerFactoryWithHandlers<_UniversalPointerHandler>(
() => _UniversalPointerHandler(onTap: onTap),
(_) {},
),
},
child: child,
);
}
class _UniversalPointerHandler extends OneSequenceGestureRecognizer {
_UniversalPointerHandler({
@required this.onTap,
}): super();
final GestureTapCallback onTap;
final _maxDistance = 18; // as in official recognizer by default
Offset _startPosition;
void _reset() {
_startPosition = null;
}
@override
void addPointer(PointerDownEvent event) {
_startPosition = event.position;
startTrackingPointer(event.pointer);
resolve(GestureDisposition.accepted);
}
@override
void handleEvent(PointerEvent event) {
if (event is PointerUpEvent) {
stopTrackingPointer(event.pointer);
if (_startPosition != null) {
onTap();
}
}
if (event is PointerMoveEvent && _startPosition != null) {
if ((event.position - _startPosition).distance > _maxDistance) {
rejectGesture(event.pointer);
_reset();
}
}
if (event is PointerCancelEvent || event is PointerExitEvent || event is PointerRemovedEvent) {
_reset();
}
}
@override
void resolve(GestureDisposition disposition) {
if (disposition == GestureDisposition.rejected) {
_reset();
}
super.resolve(disposition);
}
@override
void didStopTrackingLastPointer(int pointer) {}
@override
String get debugDescription => "_UniversalPointerHandler: Custom Gesture Recognizer";
}
UPDATE Don't forget to import this:
import 'package:flutter/gestures.dart';
You can call todo1() in the nested onTap callback:
GestureDetector(
onTap: () {
todo1();
},
child: GestureDetector(
onTap: () {
todo2();
todo1();
},
child: Text("Nested Gesture")))
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With