Created
June 18, 2024 16:01
-
-
Save Luckey-Elijah/eddb92a2c5ee76bfb679758e10bcd28f to your computer and use it in GitHub Desktop.
A useful OverlayPortal widget wrapper for building based on the anchor/target's position.
This file contains 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
import 'package:flutter/widgets.dart'; | |
class PositionedOverlayBuilder extends StatefulWidget { | |
const PositionedOverlayBuilder({ | |
required this.anchorBuilder, | |
required this.overlayChildBuilder, | |
this.dismissible = true, | |
this.barrierColor, | |
this.debugLabel, | |
super.key, | |
}); | |
final String? debugLabel; | |
final Color? barrierColor; | |
final bool dismissible; | |
final Widget Function( | |
BuildContext context, | |
OverlayPortalController controller, | |
) anchorBuilder; | |
final Widget Function( | |
BuildContext context, | |
OverlayPortalController controller, | |
Size size, | |
Offset origin, | |
) overlayChildBuilder; | |
@override | |
State<PositionedOverlayBuilder> createState() => | |
_PositionedOverlayBuilderState(); | |
} | |
class _PositionedOverlayBuilderState extends State<PositionedOverlayBuilder> { | |
late final controller = | |
OverlayPortalController(debugLabel: widget.debugLabel); | |
late final key = GlobalKey(debugLabel: widget.debugLabel); | |
Offset getWidgetOrigin(RenderBox renderBox) { | |
return renderBox.localToGlobal(Offset.zero); | |
} | |
RenderBox getRenderBox() => | |
key.currentContext!.findRenderObject()! as RenderBox; | |
@override | |
Widget build(BuildContext context) { | |
return OverlayPortal.targetsRootOverlay( | |
key: key, | |
controller: controller, | |
overlayChildBuilder: (context) { | |
final renderBox = getRenderBox(); | |
final origin = getWidgetOrigin(renderBox); | |
return Stack( | |
children: [ | |
ModalBarrier( | |
dismissible: widget.dismissible, | |
onDismiss: controller.hide, | |
color: widget.barrierColor, | |
), | |
widget.overlayChildBuilder( | |
context, | |
controller, | |
renderBox.size, | |
origin, | |
), | |
], | |
); | |
}, | |
child: widget.anchorBuilder( | |
context, | |
controller, | |
), | |
); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment