Skip to content

Instantly share code, notes, and snippets.

@nervouna
Created June 29, 2023 17:19
Show Gist options
  • Save nervouna/c59eb52a0c8ffe474e830386a0aa8c65 to your computer and use it in GitHub Desktop.
Save nervouna/c59eb52a0c8ffe474e830386a0aa8c65 to your computer and use it in GitHub Desktop.
Flutter popup menu button triggered by long press.
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
class LongPressMenuButton extends StatefulWidget {
final Widget child;
final List<PopupMenuEntry> items;
final bool enabled;
final bool hapticFeedback;
const LongPressMenuButton({
super.key,
required this.child,
required this.items,
this.enabled = true,
this.hapticFeedback = true,
});
@override
LongPressMenuButtonState createState() => LongPressMenuButtonState();
}
class LongPressMenuButtonState extends State<LongPressMenuButton> {
Offset _tapPosition = Offset.zero;
void _setTapPosition(TapDownDetails details) {
final RenderBox refBox = context.findRenderObject() as RenderBox;
setState(() => _tapPosition = refBox.localToGlobal(details.localPosition));
}
void _showContextMenu() async {
final overlay = Overlay.of(context).context.findRenderObject();
final rect = _tapPosition & const Size(40, 40);
final container = Offset.zero & overlay!.semanticBounds.size;
showMenu(
context: context,
position: RelativeRect.fromRect(rect, container),
items: widget.items,
);
if (widget.hapticFeedback) HapticFeedback.selectionClick();
}
@override
Widget build(BuildContext context) {
return widget.enabled
? GestureDetector(
onTapDown: _setTapPosition,
onLongPress: _showContextMenu,
child: widget.child,
)
: widget.child;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment