findAncestorWidgetOfExactType<T extends Widget> static method

T? findAncestorWidgetOfExactType<T extends Widget>(
  1. BuildContext context
)

Returns the nearest ancestor widget of the given type T within the current LookupBoundary of context.

T must be the type of a concrete Widget subclass.

This method behaves exactly like BuildContext.findAncestorWidgetOfExactType, except it only considers Widgets of the specified type T between the provided BuildContext and its closest LookupBoundary ancestor. Widgets past that LookupBoundary are invisible to this method. The root of the tree is treated as an implicit lookup boundary.

In general, dependOnInheritedWidgetOfExactType is more useful, since inherited widgets will trigger consumers to rebuild when they change. This method is appropriate when used in interaction event handlers (e.g. gesture callbacks) or for performing one-off tasks such as asserting that you have or don't have a widget of a specific type as an ancestor. The return value of a Widget's build method should not depend on the value returned by this method, because the build context will not rebuild if the return value of this method changes. This could lead to a situation where data used in the build method changes, but the widget is not rebuilt.

Calling this method is relatively expensive (O(N) in the depth of the tree). Only call this method if the distance from this widget to the desired ancestor is known to be small and bounded.

This method should not be called from State.deactivate or State.dispose because the widget tree is no longer stable at that time. To refer to an ancestor from one of those methods, save a reference to the ancestor by calling findAncestorWidgetOfExactType in State.didChangeDependencies.

Returns null if a widget of the requested type does not appear in the ancestors of this context.

Implementation

static T? findAncestorWidgetOfExactType<T extends Widget>(BuildContext context) {
  Element? target;
  context.visitAncestorElements((Element ancestor) {
    if (ancestor.widget.runtimeType == T) {
      target = ancestor;
      return false;
    }
    return ancestor.widget.runtimeType != LookupBoundary;
  });
  return target?.widget as T?;
}