The introduction

InheritedWidget, an important functional component of Flutter. For example, if we share data with an InheritedWidget in the root widget of our application, we can retrieve that shared data in any child widget.

didChangeDependencies

Speaking of inheritedWidgets, we have to talk about the didChangeDependencies method in the State object. The didChangeDependencies method of the child widget that relies on it is called when an InheritedWidget that uses an InheritedWidget in the parent, such as a theme or locale, changes.

In general, this method is rarely overridden by child widgets because the framework also calls the build() method after a dependency change. However, if you need to do something expensive after a dependency change, such as a network request, it’s best to do it in this method so you don’t have to do it every time you build().

Important: If the child control build method does not use InheritedShareWidget data, its didChangeDependencies will not be called

How to use it?

We use a simple count increment example to document the use of the InheritedWidget:

  1. New InheritedShareWidget Inherits the InheritedWidget as a shared data source to provide child node data to the parent node
import 'package:flutter/material.dart';

class InheritedShareWidget extends InheritedWidget {
  // Data for sharing
  final int data;
  InheritedShareWidget({this.data, Widget child}) : super(child: child);

  // Define a convenient method for child controls to obtain shared data
  static InheritedShareWidget of(BuildContext context) {

    ///When a child control dependency uses our data source, data changes trigger the didChangeDependencies method in the child control
    return context.dependOnInheritedWidgetOfExactType<InheritedShareWidget>();

    ///The didChangeDependencies method in the child control does not fire
    // return context.getElementForInheritedWidgetOfExactType<InheritedShareWidget>().widget;
  }

  @override
  bool updateShouldNotify(covariant InheritedShareWidget oldWidget) {
    // Child controls are notified only when true is returned
    returnoldWidget.data ! =this.data; }}Copy the code

Note: updateShouldNotify method, notice refers to the child controls didChangeDependencies method, the premise is the manner in which child controls use dependOnInheritedWidgetOfExactType access to share data.

  1. How do I get shared data from child nodes?
class TestShareChildWidget extends StatefulWidget {
  const TestShareChildWidget({Key key}) : super(key: key);
  @override
  _TestShareChildWidgetState createState() => _TestShareChildWidgetState();
}

class _TestShareChildWidgetState extends State<TestShareChildWidget> {
  @override
  void didChangeDependencies() {
    ///If the Build method does not use InheritedShareWidget data, its didChangeDependencies() will not be called
    super.didChangeDependencies();
    print("enter didChangeDependencies");
  }

  @override
  Widget build(BuildContext context) {
    print("enter child build");
    // Inherited Shared data
    final data = InheritedShareWidget.of(context).data.toString();
    returnText(data); }}Copy the code
  1. The two are linked by nested parent-child relationships:
class _TestInheritedWidgetState extends State<TestInheritedWidget> {
  int count = 0;

  @override
  Widget build(BuildContext context) {
    return Center(
      child: InheritedShareWidget(
        data: count,
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            TestShareChildWidget(),
            RaisedButton(
                child: Text('add'), onPressed: () { setState(() { ++count; }); })],),),); }}Copy the code

Notice that the demo uses setState to manually trigger the refresh control for the ++count operation.

conclusion

  • InheritedWidgetOnly gives us the ability to share data and control whether or not it triggers before builddidChangeDependencies Ability. It’s not actively triggeredbuildMethod, ifbuildIt wasn’t triggered, sodidChangeDependencies It won’t be triggered.

Extra extension

InheritedWidget data sharing capability is not affected by Navigator push new page. Unlike native, the page jump of Flutter does not manage a stack. Navigator essentially uses overlay to manage a stack widget. Therefore, the data sharing condition for InheritedWidget based on parent-child relationship management is not broken