OverlayPortal class

A widget that renders its overlay child on an Overlay.

The overlay child is initially hidden until OverlayPortalController.show is called on the associated controller. The OverlayPortal uses overlayChildBuilder to build its overlay child and renders it on the specified Overlay as if it was inserted using an OverlayEntry, while it can depend on the same set of InheritedWidgets (such as Theme) that this widget can depend on.

This widget requires an Overlay ancestor in the widget tree when its overlay child is showing. The overlay child is rendered by the Overlay ancestor, not by the widget itself. This allows the overlay child to float above other widgets, independent of its position in the widget tree.

When OverlayPortalController.hide is called, the widget built using overlayChildBuilder will be removed from the widget tree the next time the widget rebuilds. Stateful descendants in the overlay child subtree may lose states as a result.

This example uses an OverlayPortal to build a tooltip that becomes visible when the user taps on the child widget. There's a DefaultTextStyle above the OverlayPortal controlling the TextStyle of both the child widget and the widget overlayChildBuilder builds, which isn't otherwise doable if the tooltip was added as an OverlayEntry.
link

To create a local project with this code sample, run:
flutter create --sample=widgets.OverlayPortal.1 mysample

Paint Order

In an Overlay, an overlay child is painted after the OverlayEntry associated with its OverlayPortal (that is, the OverlayEntry closest to the OverlayPortal in the widget tree, which usually represents the enclosing Route), and before the next OverlayEntry.

When an OverlayEntry has multiple associated OverlayPortals, the paint order between their overlay children is the order in which OverlayPortalController.show was called. The last OverlayPortal to have called show gets to paint its overlay child in the foreground.

Semantics

The semantics subtree generated by the overlay child is considered attached to OverlayPortal instead of the target Overlay. An OverlayPortal's semantics subtree can be dropped from the semantics tree due to invisibility while the overlay child is still visible (for example, when the OverlayPortal is completely invisible in a ListView but kept alive by a KeepAlive widget). When this happens the semantics subtree generated by the overlay child is also dropped, even if the overlay child is still visible on screen.

Differences between OverlayPortal and OverlayEntry

The main difference between OverlayEntry and OverlayPortal is that OverlayEntry builds its widget subtree as a child of the target Overlay, while OverlayPortal uses OverlayPortal.overlayChildBuilder to build a child widget of itself. This allows OverlayPortal's overlay child to depend on the same set of InheritedWidgets as OverlayPortal, and it's also guaranteed that the overlay child will not outlive its OverlayPortal.

On the other hand, OverlayPortal's implementation is more complex. For instance, it does a bit more work than a regular widget during global key reparenting. If the content to be shown on the Overlay doesn't benefit from being a part of OverlayPortal's subtree, consider using an OverlayEntry instead.

See also:

Inheritance

Constructors

OverlayPortal({Key? key, required OverlayPortalController controller, required WidgetBuilder overlayChildBuilder, Widget? child})
Creates an OverlayPortal that renders the widget overlayChildBuilder builds on the closest Overlay when OverlayPortalController.show is called.
const
OverlayPortal.targetsRootOverlay({Key? key, required OverlayPortalController controller, required WidgetBuilder overlayChildBuilder, Widget? child})
Creates an OverlayPortal that renders the widget overlayChildBuilder builds on the root Overlay when OverlayPortalController.show is called.
const

Properties

child Widget?
A widget below this widget in the tree.
final
controller OverlayPortalController
The controller to show, hide and bring to top the overlay child.
final
hashCode int
The hash code for this object.
no setterinherited
key Key?
Controls how one widget replaces another widget in the tree.
finalinherited
overlayChildBuilder WidgetBuilder
A WidgetBuilder used to build a widget below this widget in the tree, that renders on the closest Overlay.
final
runtimeType Type
A representation of the runtime type of the object.
no setterinherited

Methods

createElement() StatefulElement
Creates a StatefulElement to manage this widget's location in the tree.
inherited
createState() State<OverlayPortal>
Creates the mutable state for this widget at a given location in the tree.
override
debugDescribeChildren() List<DiagnosticsNode>
Returns a list of DiagnosticsNode objects describing this node's children.
inherited
debugFillProperties(DiagnosticPropertiesBuilder properties) → void
Add additional properties associated with the node.
inherited
noSuchMethod(Invocation invocation) → dynamic
Invoked when a nonexistent method or property is accessed.
inherited
toDiagnosticsNode({String? name, DiagnosticsTreeStyle? style}) DiagnosticsNode
Returns a debug representation of the object that is used by debugging tools and by DiagnosticsNode.toStringDeep.
inherited
toString({DiagnosticLevel minLevel = DiagnosticLevel.info}) String
A string representation of this object.
inherited
toStringDeep({String prefixLineOne = '', String? prefixOtherLines, DiagnosticLevel minLevel = DiagnosticLevel.debug, int wrapWidth = 65}) String
Returns a string representation of this node and its descendants.
inherited
toStringShallow({String joiner = ', ', DiagnosticLevel minLevel = DiagnosticLevel.debug}) String
Returns a one-line detailed description of the object.
inherited
toStringShort() String
A short, textual description of this widget.
inherited

Operators

operator ==(Object other) bool
The equality operator.
inherited