Flutter BuildContext

Element through the interface implements BuildContext BuildContext expose a few methods and objects to developers Element used to obtain relevant information. Exposing the entire element to the developer can easily contaminate the component, such as various lifecycle methods or update operations. Here are some of the methods that BuildContext provides for developers to use (excluding deprecated methods, which generally have methods to implement the same functionality via generics).

dependOnInheritedElement

InheritedWidget gets the appropriate InheritedWidget from the InheritedElement passed in, and adds the current Element to the InheritedElement’s _dependents, triggering the current element’s if the InheritedElement is updated The update.

InheritedWidget dependOnInheritedElement(InheritedElement ancestor, { Object aspect });
Copy the code

dependOnInheritedWidgetOfExactType

Obtain the appropriate InheritedElement by passing in the InheritedWidget generic, and then return the appropriate InheritedWidget object by dependOnInheritedElement above.

This method binds the component to the InheritedWidget’s prior relationship, and triggers the rebuild of the InheritedWidget if the InheritedWidget is updated.

T dependOnInheritedWidgetOfExactType<T extends InheritedWidget>({Object aspect});
Copy the code

Theme. Of (context); Theme. Of (context);

Demo:

class Theme{ static ThemeData of(BuildContext context, { bool shadowThemeOnly = false }) { final _InheritedTheme inheritedTheme = context.dependOnInheritedWidgetOfExactType<_InheritedTheme>(); . }Copy the code

To get an InheritedWidget object using the InheritedWidget generic, take a look at how the InheritedWidget works.

getElementForInheritedWidgetOfExactType

Through InheritedWidget generic T get its Element, it would differ from dependOnInheritedWidgetOfExactType is create the binding relationship between the two widgets

It does not bind the connection between the calling component and the InheritedWidget component, meaning that when the InheritedWidget component changes, it does not trigger an update to the widget in which the method is called.

InheritedElement getElementForInheritedWidgetOfExactType<T extends InheritedWidget>();
Copy the code

findAncestorWidgetOfExactType

Through recursive element. _parent get element. Widget. RuntimeType = = T widget

  T findAncestorWidgetOfExactType<T extends Widget>();
Copy the code

Take a look at Element’s implementation code for this

@ override T findAncestorWidgetOfExactType < T extends widgets > () {/ / / get the parent element element ancestor = _parent; // If the parent element is not null and the widget of the parent element is runtimeType! = generic T while (ancestor! = null && ancestor.widget.runtimeType ! // Element ancestor = ancestor._parent; return ancestor? .widget as T; }Copy the code

findAncestorStateOfType

The state of type T is recursively obtained from the passed generic T. The implementation code is similar to the above, but the logic of the loop has been changed.

T findAncestorStateOfType<T extends State>();
Copy the code

Take a look at the implementation code

@override T findAncestorStateOfType<T extends State<StatefulWidget>>() { Element ancestor = _parent; while (ancestor ! State is T) break; if (ancestor is StatefulElement && ancestor. State is T) break; ancestor = ancestor._parent; } final StatefulElement statefulAncestor = ancestor as StatefulElement; return statefulAncestor? .state as T; }Copy the code

findRootAncestorStateOfType

Through incoming TypeMatcher generic T up recursive element for the state of type T of the difference between the state and findAncestorWidgetOfExactType in one it is to obtain satisfy the conditions for the parent. Recently the state and the current function to obtain the farthest node Parent. State that satisfies the condition

T findRootAncestorStateOfType<T extends State>();
Copy the code

Take a look at the implementation code

@override T findRootAncestorStateOfType<T extends State<StatefulWidget>>() { Element ancestor = _parent; StatefulElement statefulAncestor; while (ancestor ! If (ancestor is StatefulElement && ancestor. State is T) {/// if (ancestor is StatefulElement && ancestor. State is T); statefulAncestor = ancestor; ancestor = ancestor._parent; } return statefulAncestor? .state as T; }Copy the code

findAncestorRenderObjectOfType

Get the corresponding RenderObject from the method’s generics

T findAncestorRenderObjectOfType<T extends RenderObject>();
Copy the code

So that’s the relatively common way to buildContext. In fact, we use most is dependOnInheritedWidgetOfExactType.

The end of the fireworks.