Reputation: 103
I'm working on a launcher app with gestures settings and I'm looking for a way to achieve two-finger swipe up and down gestures, i found out that it can be achieved by using RawGestureDetector and MultiDragGestureRecognizer , but I have no idea how to do it, can anyone share a code example or explain how to do it
i tried this code sample but it doesn't seem to work :
import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
class TwoFingerPointerWidget extends StatelessWidget {
final Widget child;
final OnUpdate onUpdate;
TwoFingerPointerWidget({required this.child, required this.onUpdate});
@override
Widget build(BuildContext context) {
return RawGestureDetector(
gestures: <Type, GestureRecognizerFactory>{
CustomVerticalMultiDragGestureRecognizer:
GestureRecognizerFactoryWithHandlers<
CustomVerticalMultiDragGestureRecognizer>(
() => CustomVerticalMultiDragGestureRecognizer(debugOwner: null),
(CustomVerticalMultiDragGestureRecognizer instance) {
instance.onStart = (Offset position) {
return CustomDrag(events: instance.events, onUpdate: onUpdate);
};
},
),
},
child: child,
);
}
}
typedef OnUpdate(DragUpdateDetails details);
class CustomDrag extends Drag {
final List<PointerDownEvent> events;
final OnUpdate onUpdate;
CustomDrag({required this.events, required this.onUpdate});
@override
void update(DragUpdateDetails details) {
super.update(details);
final delta = details.delta;
if (delta.dy.abs() > 0 && events.length == 2) {
onUpdate.call(DragUpdateDetails(
sourceTimeStamp: details.sourceTimeStamp,
delta: Offset(0, delta.dy),
primaryDelta: details.primaryDelta,
globalPosition: details.globalPosition,
localPosition: details.localPosition,
));
}
}
@override
void end(DragEndDetails details) {
super.end(details);
}
}
class CustomVerticalMultiDragGestureRecognizer
extends MultiDragGestureRecognizer {
final List<PointerDownEvent> events = [];
CustomVerticalMultiDragGestureRecognizer({required Object? debugOwner})
: super(debugOwner: debugOwner);
@override
createNewPointerState(PointerDownEvent event) {
events.add(event);
return _CustomVerticalPointerState(event.position, onDisposeState: () {
events.remove(event);
});
}
@override
String get debugDescription => 'custom vertical multidrag';
}
typedef OnDisposeState();
class _CustomVerticalPointerState extends MultiDragPointerState {
final OnDisposeState onDisposeState;
_CustomVerticalPointerState(Offset initialPosition,
{required this.onDisposeState})
: super(initialPosition, PointerDeviceKind.touch, null);
@override
void checkForResolutionAfterMove() {
if (pendingDelta!.dy.abs() > kTouchSlop) {
resolve(GestureDisposition.accepted);
}
}
@override
void accepted(GestureMultiDragStartCallback starter) {
starter(initialPosition);
}
@override
void dispose() {
onDisposeState.call();
super.dispose();
}
}
Upvotes: 3
Views: 3048
Reputation: 103
So i just found a solution , not the best one but it still works ,for anyone looking you have to work around the listener class , here is my code :
final events = [];
Listener(
onPointerDown: (event) {
events.add(event.pointer);
},
onPointerUp: (event) {
events.clear();
},
onPointerMove: (event) {
if (events.length == 2) {
int sensitivity = 8;
if (event.delta.dy > sensitivity) {
// code for two finger swipe up event
} else if (event.delta.dy < -sensitivity) {
// code for two finger swipe down event
}
}
},
Upvotes: 4