skills/flutter/references/advanced-gestures.md

269 lines
5.0 KiB
Markdown

---
name: advanced-gestures
description: Flutter gestures - GestureDetector, GestureRecognizer, drag and drop, and gesture handling
---
# Gestures
Flutter provides comprehensive gesture detection and handling capabilities.
## GestureDetector
Detect various gestures on widgets.
```dart
GestureDetector(
onTap: () {
// Handle tap
},
onDoubleTap: () {
// Handle double tap
},
onLongPress: () {
// Handle long press
},
onPanUpdate: (details) {
// Handle pan (drag)
print('Delta: ${details.delta}');
},
onScaleUpdate: (details) {
// Handle scale (pinch)
print('Scale: ${details.scale}');
},
child: Container(
width: 100,
height: 100,
color: Colors.blue,
),
)
```
## Tap Gestures
```dart
GestureDetector(
onTap: () {
print('Tapped');
},
onTapDown: (details) {
print('Tap down at ${details.localPosition}');
},
onTapUp: (details) {
print('Tap up at ${details.localPosition}');
},
onTapCancel: () {
print('Tap cancelled');
},
child: Container(...),
)
```
## Long Press
```dart
GestureDetector(
onLongPress: () {
print('Long pressed');
},
onLongPressStart: (details) {
print('Long press started');
},
onLongPressEnd: (details) {
print('Long press ended');
},
onLongPressMoveUpdate: (details) {
print('Long press moved: ${details.localPosition}');
},
child: Container(...),
)
```
## Pan Gestures (Drag)
```dart
class DraggableWidget extends StatefulWidget {
const DraggableWidget({super.key});
@override
State<DraggableWidget> createState() => _DraggableWidgetState();
}
class _DraggableWidgetState extends State<DraggableWidget> {
Offset _position = Offset.zero;
@override
Widget build(BuildContext context) {
return Positioned(
left: _position.dx,
top: _position.dy,
child: GestureDetector(
onPanUpdate: (details) {
setState(() {
_position += details.delta;
});
},
child: Container(
width: 100,
height: 100,
color: Colors.blue,
),
),
);
}
}
```
## Scale Gestures (Pinch)
```dart
class ScalableWidget extends StatefulWidget {
const ScalableWidget({super.key});
@override
State<ScalableWidget> createState() => _ScalableWidgetState();
}
class _ScalableWidgetState extends State<ScalableWidget> {
double _scale = 1.0;
@override
Widget build(BuildContext context) {
return GestureDetector(
onScaleUpdate: (details) {
setState(() {
_scale = details.scale;
});
},
child: Transform.scale(
scale: _scale,
child: Container(
width: 100,
height: 100,
color: Colors.blue,
),
),
);
}
}
```
## GestureRecognizer
Create custom gesture recognizers.
```dart
final _tapRecognizer = TapGestureRecognizer()
..onTap = () {
print('Custom tap');
};
RichText(
text: TextSpan(
text: 'Tap ',
children: [
TextSpan(
text: 'here',
style: TextStyle(color: Colors.blue),
recognizer: _tapRecognizer,
),
],
),
)
@override
void dispose() {
_tapRecognizer.dispose();
super.dispose();
}
```
## Drag and Drop
Use Draggable and DragTarget for drag and drop.
```dart
// Draggable widget
Draggable<String>(
data: 'data',
feedback: Container(
width: 100,
height: 100,
color: Colors.blue.withOpacity(0.5),
),
childWhenDragging: Container(
width: 100,
height: 100,
color: Colors.grey,
),
child: Container(
width: 100,
height: 100,
color: Colors.blue,
child: const Center(child: Text('Drag me')),
),
)
// Drop target
DragTarget<String>(
onAccept: (data) {
print('Accepted: $data');
},
builder: (context, candidateData, rejectedData) {
return Container(
width: 200,
height: 200,
color: candidateData.isNotEmpty ? Colors.green : Colors.grey,
child: const Center(child: Text('Drop here')),
);
},
)
```
## Gesture Behavior
Control gesture behavior.
```dart
GestureDetector(
behavior: HitTestBehavior.opaque, // opaque, translucent, deferToChild
onTap: () {},
child: Container(...),
)
```
## Gesture Conflicts
Handle multiple gesture recognizers.
```dart
GestureDetector(
onTap: () {
print('Tap');
},
child: GestureDetector(
onLongPress: () {
print('Long press');
},
child: Container(...),
),
)
```
## Key Points
- Use `GestureDetector` for basic gesture detection
- Handle tap, double tap, long press gestures
- Use `onPanUpdate` for drag gestures
- Use `onScaleUpdate` for pinch/zoom gestures
- Use `Draggable` and `DragTarget` for drag and drop
- Use `GestureRecognizer` for custom gesture handling
- Set `behavior` to control hit testing
- Dispose gesture recognizers to prevent leaks
- GestureDetector can detect multiple gesture types simultaneously
<!--
Source references:
- https://github.com/flutter/flutter/tree/main/packages/flutter/lib/src/widgets/gesture_detector.dart
- https://docs.flutter.dev/development/ui/advanced/gestures
-->