Nested GestureDetector OnTap Functions
Solution 1
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';
Solution 2
You can call todo1() in the nested onTap callback:
GestureDetector(
onTap: () {
todo1();
},
child: GestureDetector(
onTap: () {
todo2();
todo1();
},
child: Text("Nested Gesture")))
aLL
I just wanted to earn the Autobiographer badge so I wrote this
Updated on December 11, 2022Comments
-
aLL over 1 year
I have nested
GestureDetetor
s but problem is that only the childGestureDetector
'sonTap
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()
andtodo2()
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