“This is the 17th day of my participation in the Gwen Challenge in November. See details of the event: The Last Gwen Challenge in 2021”.

Dart has some important points to know in the first few articles. We’ve seen some simple processes in runApp() and how they work. We also learned a few simple things about StatelessWidgets, statefulWidgets, and BuildContext in the Widget tree to traverse context. We mentioned that inheritedWidgets are important. Today we’re going to take a look at the InheritedWidget.

What is a InheritedWidget

The InheritedWidget is just a simple widget. It is immutable and does nothing but save data. If we refresh it, we need to rebuild it. Inheritedwidgets pass data from the ancestor widget to a descendant widget that may be deep in the widget tree.

const InheritedWidget({Key? key, required Widget child }) : super(key: key, child: child);
Copy the code

The InheritedWidget widget of Flutter itself:

Theme.of(context).textTheme
MediaQuery.of(context).size
Copy the code

There is a special method called of() that can access properties anywhere in its Widget tree.

When instantiating a InheritedWidget, then call context. InheritedWidgetOfExactType (or of); This means it listens for Element with your InheritedWidget. Each time Element acquires a new widget, it forces a refresh of the widget that called the previous method. When you replace an existing InheritedWidget with a new one, the system changes the notification bound widget.

The actual use

First, create your own class to extend the InheritedWidget to pass data in your project.

class ColorInfo extends InheritedWidget { ColorInfo({Key? key, required this.child}) : super(key: key, child: child); final Widget child; static ColorInfo? of(BuildContext context) { return context.dependOnInheritedWidgetOfExactType<Name>(); } @override bool updateShouldNotify(ColorInfo oldWidget) { return true; }}Copy the code

The of method is a convention for inheritedWidgets to more easily access your data from child widgets. The updateShouldNotify method tells us whether we should redraw the data-dependent widget when the data changes, and the oldWidget parameter allows you to compare the previous data in the InheritedWidget to the new data.

inheritFromWidgetOfExactType

@override InheritedWidget inheritFromWidgetOfExactType(Type targetType, Final InheritedElement ancestor = _inheritedWidgets == null? null : _inheritedWidgets[targetType]; if (ancestor ! Var inheritFromElement(); var inheritFromElement(); } _hadUnsatisfiedDependencies = true; return null; } @override InheritedWidget inheritFromElement(InheritedElement ancestor, { Object aspect }) { _dependencies ?? = HashSet<InheritedElement>(); _dependencies.add(ancestor); [dependents] [dependents] = value (); // if (()) [dependents[dependent] = value ()); // if (()) [dependents[dependent] = value ()); ancestor.updateDependencies(this, aspect); return ancestor.widget; } @override void notifyClients(InheritedWidget oldWidget) { for (Element dependent in _dependents.keys) { notifyDependent(oldWidget, dependent); }}Copy the code
  • In a Shared map_inheritedWidgetsIf found, addinheritFromElementProcess, and then return what you foundInheritedWidget
  • Will the currentElementTo join theInheritedElementthe_dependentsIn this map. And to theupdateDependenciesTake care of it. InWidgetIn returnInheritedElement.

Does creating a new InheritedWidget rebuild the entire tree?

Not necessarily. Because your new InheritedWidget may have exactly the same child widget (the same instance) as before. Widgets that have the same instance as before are not rebuilt.