PS: Your plan is perfect, but the world is changing so fast.

In my previous article, I studied image loading and source code analysis in Flutter. Those of you who have done mobile development know that the life cycle of a Flutter component is the same as that of a Flutter component. It is very important to understand and learn the life cycle of a Flutter component.

  • Detailed description of the use of the Flutter Navigator
  • Detailed description of the Flex layout of the Flutter series
  • Detailed explanation of image loading of the Flutter series

This article will focus on the lifecycle of widgets in Flutter as follows:

  1. StatelessWidget
  2. StatefulWidget
  3. State Indicates the life cycle status
  4. State Lifecycle method

StatelessWidget

Components derived from StatelessWidget are stateless components. Stateless components are rendered only once during construction and do not support dynamic changes. That is, they cannot be redrawn by other user operations and can only be built by receiving the parameters passed in as follows:

/// StatelessWidget
/// represents a stateless Widget
class StatelessSamplePage extends StatelessWidget {

  // External incoming data
  final String data;
  StatelessSamplePage(this.data);

  @override
  Widget build(BuildContext context) {
    returnContainer( color: Colors.lightBlue, child: Text(data), ); }}Copy the code

The arguments passed in above can only be final, otherwise the following warning will appear:

This class (or a class which this class inherits from) is marked as '@immutable', but one or more of its instance fields are not final: StatelessSamplePage.data
Copy the code

The prompt Widget is modified by the @immutable annotation as follows:

@immutable
abstract class Widget extends DiagnosticableTree {
Copy the code

Variables can only be modified with final. Variables modified with final in Dart can only be initialized once, which is consistent with the stateless nature of statelessWidgets.

StatefulWidget

A component derived from StatefulWidget is a stateful component that supports building widgets multiple times as the data changes to render a dynamic interface. If you want to implement an interface that displays the current time in real time, StatelessWidget obviously cannot be done. This can only be done using a stateful StatefulWidget like this:

/// StatefulWidget
/// represents a stateful Widget
class StatefulSamplePage extends StatefulWidget {
  @override
  _StatefulSamplePageState createState(a) => _StatefulSamplePageState();
}

class _StatefulSamplePageState extends State<StatefulSamplePage> {
  DateFormat _dateFormat;
  String _currentTime;
  Timer _timer;

  @override
  void initState(a) {
    super.initState();
    _dateFormat = new DateFormat("yyyy-MM-dd HH:mm:ss");
    // Initialize the current time
    _currentTime = _dateFormat.format(DateTime.now());
    // Update time
    _startTime();
  }

  @override
  Widget build(BuildContext context) {
    return Center(
      child: Scaffold(
        appBar: AppBar(
          title: Text("Stateful Widget sample"),
          centerTitle: true,
        ),
        body: Align(
          alignment: Alignment.topCenter,
          child: Text("Current time: $_currentTime"),),),); }@override
  void dispose(a) {
    super.dispose();
    if(_timer! =null){
      _timer.cancel();
    }
  }

  _startTime() {
    const Duration duration = Duration(seconds: 1);
    _timer = Timer.periodic(
        duration,
        (Timer timer) => {
              // Refresh the interface statussetState(() { _currentTime = _dateFormat.format(DateTime.now()); })}); }}Copy the code

The effect is as follows:

In fact, there is no difference between a StatelessWidget and a StatefulWidget if it is a static interface. The only difference is that the StatefulWidget can trigger a rebuild of the Widget using the setState method. The State class was Stateless -> Stateful bridge.

State Indicates the life cycle status

The Flutter life cycle is actually the life cycle of each component:

  • StatelessWidget: The life cycle of a stateless component is only the build process;
  • StatefulWidget: The life cycle of a stateless component refers to the life cycle of State.

The Flutter life cycle is actually the life cycle of stateless components, i.e. the life cycle of State, as shown in the following figure:

The life cycle states of each State above are mainly three:

  • Created: The State created when the createState method is called is in the Created State;
  • Dirty: The state of the Widget when the data changes when a method such as setState is called, but the Widget has not been rebuilt;
  • Clean: refers to the state after the Widget is built;
  • Defunct: The State after the call of state. dispose, in which the Widget has been destroyed and cannot be rebuilt.

State Lifecycle method

The life cycle of a stateful component is the life cycle of State, and its specific call process and build trigger time are shown below:

The specific meaning of its life cycle method is as follows:

  • CreateState: StatefulWidget used to createState;
  • InitState: Initializes State, such as variables.
  • DidChangeDependencies: Call after initState, or use the InheritedWidgets component, which is available for Flutter state management.
  • Build: for building widgets;
  • Deactivate: Called after the Widget containing the State object is removed. If the Widget is not added to another Widget tree after being removed, dispose method is called again.
  • Dispose: This method is called to release the resources occupied by the Widget.
  • Reassemble: Used for development, called when hot reloads, and then builds again;
  • DidUpdateWidget: The didUpdateWidget method of the child Widget is called when the parent Widget is built.

Add logging to the corresponding Widget lifecycle methods to verify the execution of the above lifecycle methods. The source code for the parent Widget is as follows:

const String TAG = "Flutter";
/// Widget lifecycle
class WidgetLifecycleSamplePage extends StatefulWidget {
  @override
  _WidgetLifecycleSamplePageState createState(a) {
    Log.info(TAG, "parent createState");
    return_WidgetLifecycleSamplePageState(); }}class _WidgetLifecycleSamplePageState extends State<WidgetLifecycleSamplePage> {

  num _count = 0;

  @override
  void initState(a) {
    super.initState();
    Log.info(TAG, "parent initState");
  }

  @override
  Widget build(BuildContext context) {
    Log.info(TAG, "parent build");
    return Scaffold(
      appBar: AppBar(
        title: Text("Widget Lifecycle Sample"),
        centerTitle: true,
      ),
      body: Column(
        children: <Widget>[
          Center(
            child: RaisedButton(
                textColor:Colors.white,
                color: Colors.lightBlue,
                child: Text("parent->setState:$_count",style: TextStyle(color: Colors.white),),
                onPressed: (){
                  setState(() {
                    Log.info(TAG, "parent setState");
                    _count++;
                  });
                }),
          ),
          SubWidgetLifecycleSamplePage(),
        ],
      )
    );
  }

  @override
  void didUpdateWidget(WidgetLifecycleSamplePage oldWidget) {
    super.didUpdateWidget(oldWidget);
    Log.info(TAG, "parent didUpdateWidget");
  }

  @override
  void didChangeDependencies(a) {
    super.didChangeDependencies();
    Log.info(TAG, "parent didChangeDependencies");
  }

  @override
  void deactivate(a) {
    super.deactivate();
    Log.info(TAG, "parent deactivate");
  }

  @override
  void reassemble(a) {
    super.reassemble();
    Log.info(TAG, "parent reassemble");
  }

  @override
  void dispose(a) {
    super.dispose();
    Log.info(TAG, "parent dispose"); }}/ / / child widgets
class SubWidgetLifecycleSamplePage extends StatefulWidget {
  @override
  _SubWidgetLifecycleSamplePageState createState(a) {
    Log.info(TAG, "sub createState");
    return_SubWidgetLifecycleSamplePageState(); }}Copy the code

Lifecycle can be obtained from the background of the public account. The code will look like this:

Its corresponding life week and its method call are as follows:

Analysis is as follows:

  1. The Widget initialization flow refers to the lifecycle flow that enters the page where the Widge is running. The parent Widget, the child Widget, and then the createState, initState, DidChangeDepAndConstruction, and Build methods are called.
  2. The child Widget calls the didUpdateWidget method because the parent Widget’s build is triggered when the parent Widget seteState updates its data.
  3. Other processes, such as hot reloading and Widget destruction, are the same as the State lifecycle method flowchart above and will not be described here.

Lifecycle can be accessed by Lifecycle in the background of the official account. For more information, see wechat official account.