Skip to content

Instantly share code, notes, and snippets.

@guptahitesh121
Last active September 14, 2022 06:14
Show Gist options
  • Save guptahitesh121/ca7fa34d73b8b024823c85dd0c7f687d to your computer and use it in GitHub Desktop.
Save guptahitesh121/ca7fa34d73b8b024823c85dd0c7f687d to your computer and use it in GitHub Desktop.
Flutter Sample code to detect 2 finger swipe vertically using `RawGestureDetector` and `MultiDragGestureRecognizer`.
import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Swipe Demo',
debugShowCheckedModeBanner: false,
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: SwipeDemo(),
);
}
}
class SwipeDemo extends StatefulWidget {
@override
SwipeDemoState createState() => SwipeDemoState();
}
class SwipeDemoState extends State<SwipeDemo> {
Offset offset = Offset.zero;
@override
Widget build(BuildContext context) {
return SafeArea(
child: TwoFingerPointerWidget(
onUpdate: (details) {
setState(() {
offset += details.delta;
});
},
child: Container(
alignment: Alignment.center,
color: Colors.white,
child: Transform.translate(
offset: offset,
child: Container(
width: 100,
height: 100,
color: Colors.red,
),
),
),
),
);
}
}
class TwoFingerPointerWidget extends StatelessWidget {
final Widget child;
final OnUpdate onUpdate;
TwoFingerPointerWidget({this.child, this.onUpdate});
@override
Widget build(BuildContext context) {
return RawGestureDetector(
gestures: <Type, GestureRecognizerFactory>{
CustomVerticalMultiDragGestureRecognizer: GestureRecognizerFactoryWithHandlers<CustomVerticalMultiDragGestureRecognizer>(
() => CustomVerticalMultiDragGestureRecognizer(),
(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({this.events, 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<_CustomVerticalPointerState> {
final List<PointerDownEvent> events = [];
@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, {this.onDisposeState}) : super(initialPosition);
@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();
}
}
@awaik
Copy link

awaik commented Aug 17, 2022

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment