Created
March 15, 2023 17:09
-
-
Save tarek360/1e0695ec9cdf8c6659830efa264e60cd to your computer and use it in GitHub Desktop.
RelativePositionOverlay to show a context popup in a position relative to the another widget position
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class RelativePositionOverlay extends StatefulWidget { | |
const RelativePositionOverlay({ | |
super.key, | |
required this.popupBuilder, | |
required this.child, | |
this.popupOffset = Offset.zero, | |
}); | |
final WidgetBuilder popupBuilder; | |
final Widget child; | |
final Offset popupOffset; | |
@override | |
State<RelativePositionOverlay> createState() => _RelativePositionOverlayState(); | |
} | |
class _RelativePositionOverlayState extends State<RelativePositionOverlay> { | |
final FocusNode _focusNode = FocusNode(); | |
late OverlayEntry _overlayEntry; | |
final LayerLink _layerLink = LayerLink(); | |
@override | |
void initState() { | |
super.initState(); | |
_focusNode.addListener(() { | |
if (_focusNode.hasFocus) { | |
_overlayEntry = _createOverlayEntry(); | |
Overlay.of(context).insert(_overlayEntry); | |
} else { | |
_overlayEntry.remove(); | |
} | |
}); | |
} | |
OverlayEntry _createOverlayEntry() { | |
return OverlayEntry( | |
builder: (context) => Positioned( | |
left: 0, | |
child: CompositedTransformFollower( | |
link: _layerLink, | |
showWhenUnlinked: false, | |
offset: widget.popupOffset, | |
child: widget.popupBuilder(context), | |
), | |
)); | |
} | |
@override | |
Widget build(BuildContext context) { | |
return CompositedTransformTarget( | |
link: _layerLink, | |
child: Focus( | |
focusNode: _focusNode, | |
child: widget.child, | |
), | |
); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment