InheritedModel<T> class Null safety

An InheritedWidget that's intended to be used as the base class for models whose dependents may only depend on one part or "aspect" of the overall model.

An inherited widget's dependents are unconditionally rebuilt when the inherited widget changes per InheritedWidget.updateShouldNotify. This widget is similar except that dependents aren't rebuilt unconditionally.

Widgets that depend on an InheritedModel qualify their dependence with a value that indicates what "aspect" of the model they depend on. When the model is rebuilt, dependents will also be rebuilt, but only if there was a change in the model that corresponds to the aspect they provided.

The type parameter T is the type of the model aspect objects.

Widgets create a dependency on an InheritedModel with a static method: InheritedModel.inheritFrom. This method's context parameter defines the subtree that will be rebuilt when the model changes. Typically the inheritFrom method is called from a model-specific static of method. For example:

class MyModel extends InheritedModel<String> {
  // ...
  static MyModel? of(BuildContext context, String aspect) {
    return InheritedModel.inheritFrom<MyModel>(context, aspect: aspect);
  }
}

Calling MyModel.of(context, 'foo') means that context should only be rebuilt when the foo aspect of MyModel changes. If the aspect is null, then the model supports all aspects.

When the inherited model is rebuilt the updateShouldNotify and updateShouldNotifyDependent methods are used to decide what should be rebuilt. If updateShouldNotify returns true, then the inherited model's updateShouldNotifyDependent method is tested for each dependent and the set of aspect objects it depends on. The updateShouldNotifyDependent method must compare the set of aspect dependencies with the changes in the model itself. For example:
class ABModel extends InheritedModel<String> {
  const ABModel({
   super.key,
   this.a,
   this.b,
   required super.child,
  });

  final int? a;
  final int? b;

  @override
  bool updateShouldNotify(ABModel oldWidget) {
    return a != oldWidget.a || b != oldWidget.b;
  }

  @override
  bool updateShouldNotifyDependent(ABModel oldWidget, Set<String> dependencies) {
    return (a != oldWidget.a && dependencies.contains('a'))
      || (b != oldWidget.b && dependencies.contains('b'));
  }

  // ...
}

In the previous example the dependencies checked by updateShouldNotifyDependent are just the aspect strings passed to dependOnInheritedWidgetOfExactType. They're represented as a Set because one Widget can depend on more than one aspect of the model. If a widget depends on the model but doesn't specify an aspect, then changes in the model will cause the widget to be rebuilt unconditionally.

This example shows how to implement InheritedModel to rebuild a widget based on a qualified dependence. When tapped on the "Resize Logo" button only the logo widget is rebuilt while the background widget remains unaffected.
To create a local project with this code sample, run:
flutter create --sample=widgets.InheritedModel.2 mysample

See also:

  • InheritedWidget, an inherited widget that only notifies dependents when its value is different.
  • InheritedNotifier, an inherited widget whose value can be a Listenable, and which will notify dependents whenever the value sends notifications.
Inheritance

Constructors

InheritedModel({Key? key, required Widget child})
Creates an inherited widget that supports dependencies qualified by "aspects", i.e. a descendant widget can indicate that it should only be rebuilt if a specific aspect of the model changes.
const

Properties

child Widget
The widget below this widget in the tree.
finalinherited
hashCode int
The hash code for this object.
nonVirtual">@nonVirtualread-onlyinherited
key Key?
Controls how one widget replaces another widget in the tree.
finalinherited
runtimeType Type
A representation of the runtime type of the object.
read-onlyinherited

Methods

createElement() InheritedModelElement<T>
Inflates this configuration to a concrete instance.
override
debugDescribeChildren() List<DiagnosticsNode>
Returns a list of DiagnosticsNode objects describing this node's children.
protected">@protectedinherited
debugFillProperties(DiagnosticPropertiesBuilder properties) → void
Add additional properties associated with the node.
inherited
isSupportedAspect(Object aspect) bool
Returns true if this model supports the given aspect.
protected">@protected
noSuchMethod(Invocation invocation) → dynamic
Invoked when a non-existent 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}) 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.
protected">@protectedinherited
updateShouldNotifyDependent(covariant InheritedModel<T> oldWidget, Set<T> dependencies) bool
Return true if the changes between this model and oldWidget match any of the dependencies.
protected">@protected

Operators

operator ==(Object other) bool
The equality operator.
nonVirtual">@nonVirtualinherited

Static Methods

inheritFrom<T extends InheritedModel<Object>>(BuildContext context, {Object? aspect}) → T?
Makes context dependent on the specified aspect of an InheritedModel of type T.