LookupBoundary class

A lookup boundary controls what entities are visible to descendants of the boundary via the static lookup methods provided by the boundary.

The static lookup methods of the boundary mirror the lookup methods by the same name exposed on BuildContext and they can be used as direct replacements. Unlike the methods on BuildContext, these methods do not find any ancestor entities of the closest LookupBoundary surrounding the provided BuildContext. The root of the tree is an implicit lookup boundary.

In the example below, the LookupBoundary.findAncestorWidgetOfExactType call returns null because the LookupBoundary "hides" MyWidget from the BuildContext that was queried.
link
MyWidget(
  child: LookupBoundary(
    child: Builder(
      builder: (BuildContext context) {
        MyWidget? widget = LookupBoundary.findAncestorWidgetOfExactType<MyWidget>(context);
        return Text('$widget'); // "null"
      },
    ),
  ),
)

A LookupBoundary only affects the behavior of the static lookup methods defined on the boundary. It does not affect the behavior of the lookup methods defined on BuildContext.

A LookupBoundary is rarely instantiated directly. They are inserted at locations of the widget tree where the render tree diverges from the element tree, which is rather uncommon. Such anomalies are created by RenderObjectElements that don't attach their RenderObject to the closest ancestor RenderObjectElement, e.g. because they bootstrap a separate stand-alone render tree. This behavior breaks the assumption some widgets have about the structure of the render tree: These widgets may try to reach out to an ancestor widget, assuming that their associated RenderObjects are also ancestors, which due to the anomaly may not be the case. At the point where the divergence in the two trees is introduced, a LookupBoundary can be used to hide that ancestor from the querying widget. The ViewAnchor, for example, wraps its ViewAnchor.view child in a LookupBoundary because the RenderObject produced by that widget subtree is not attached to the render tree that the ViewAnchor itself belongs to.

As an example, Material.of relies on lookup boundaries to hide the Material widget from certain descendant button widget. Buttons reach out to their Material ancestor to draw ink splashes on its associated render object. This only produces the desired effect if the button render object is a descendant of the Material render object. If the element tree and the render tree are not in sync due to anomalies described above, this may not be the case. To avoid incorrect visuals, the Material relies on lookup boundaries to hide itself from descendants in subtrees with such anomalies. Those subtrees are expected to introduce their own Material widget that buttons there can utilize without crossing a lookup boundary.

Inheritance

Constructors

LookupBoundary({Key? key, required Widget child})
Creates a LookupBoundary.
const

Properties

child Widget
The widget below this widget in the tree.
finalinherited
hashCode int
The hash code for this object.
no setterinherited
key Key?
Controls how one widget replaces another widget in the tree.
finalinherited
runtimeType Type
A representation of the runtime type of the object.
no setterinherited

Methods

createElement() InheritedElement
Inflates this configuration to a concrete instance.
inherited
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
updateShouldNotify(covariant InheritedWidget oldWidget) bool
Whether the framework should notify widgets that inherit from this widget.
override

Operators

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

Static Methods

debugIsHidingAncestorRenderObjectOfType<T extends RenderObject>(BuildContext context) bool
Returns true if a LookupBoundary is hiding the nearest RenderObjectWidget with a RenderObject of the specified type T from the provided BuildContext.
debugIsHidingAncestorStateOfType<T extends State<StatefulWidget>>(BuildContext context) bool
Returns true if a LookupBoundary is hiding the nearest StatefulWidget with a State of the specified type T from the provided BuildContext.
debugIsHidingAncestorWidgetOfExactType<T extends Widget>(BuildContext context) bool
Returns true if a LookupBoundary is hiding the nearest Widget of the specified type T from the provided BuildContext.
dependOnInheritedWidgetOfExactType<T extends InheritedWidget>(BuildContext context, {Object? aspect}) → T?
Obtains the nearest widget of the given type T within the current LookupBoundary of context, which must be the type of a concrete InheritedWidget subclass, and registers the provided build context with that widget such that when that widget changes (or a new widget of that type is introduced, or the widget goes away), the build context is rebuilt so that it can obtain new values from that widget.
findAncestorRenderObjectOfType<T extends RenderObject>(BuildContext context) → T?
Returns the RenderObject object of the nearest ancestor RenderObjectWidget widget within the current LookupBoundary of context that is an instance of the given type T.
findAncestorStateOfType<T extends State<StatefulWidget>>(BuildContext context) → T?
Returns the State object of the nearest ancestor StatefulWidget widget within the current LookupBoundary of context that is an instance of the given type T.
findAncestorWidgetOfExactType<T extends Widget>(BuildContext context) → T?
Returns the nearest ancestor widget of the given type T within the current LookupBoundary of context.
findRootAncestorStateOfType<T extends State<StatefulWidget>>(BuildContext context) → T?
Returns the State object of the furthest ancestor StatefulWidget widget within the current LookupBoundary of context that is an instance of the given type T.
getElementForInheritedWidgetOfExactType<T extends InheritedWidget>(BuildContext context) InheritedElement?
Obtains the element corresponding to the nearest widget of the given type T within the current LookupBoundary of context.
visitAncestorElements(BuildContext context, ConditionalElementVisitor visitor) → void
Walks the ancestor chain, starting with the parent of the build context's widget, invoking the argument for each ancestor until a LookupBoundary or the root is reached.
visitChildElements(BuildContext context, ElementVisitor visitor) → void
Walks the non-LookupBoundary child Elements of the provided context.