The stateful widget of flutter (7)

Time:2021-1-27

Preface 1: I will update some flutter text tutorials in the next period of time

Update progress:At least two articles a week;

Update location:The first time is in the official account, and the second day is updated in nuggets, thinking and developers’ headlines.

More communication:You can add my wechat 372623326 and follow my microblog: coderwhy

I hope you canHelp forward, click to seeGive me more creative motivation.

1、 Statefulwidget

In the development process, in some cases, the data we show is not the same layer

For example, for the counter case in the default program of flutter, after clicking the + button, the number displayed needs to be + 1;

For example, in the development, we will pull down refresh, pull up load more, then the data will change;

Statelesswidget is usually used to show which data is fixed. If the data will change, we use stateful widget;

1.1. Know statefulwidget

1.1.1. Introduction to statefulwidget

If you’ve read the example program that creates flutter by default, you’ll find that it creates a stateful widget.

Why stateful widget?

  • Because in the example code, when we click the button, the data displayed on the interface will change;
  • At this point, we need onevariableTo record the current state, and then display this variable to a text widget;
  • And every timevariableWhen it changes, the content displayed on our corresponding text will also change;

But there is a problem. As I said before, the data defined in a widget is immutable and must be defined as final. Why?

  • This time, flutter decided to rebuild the whole widget once the data displayed in the widget changes;
  • In the next chapter, I will explain the rendering principle of flutter. Flutter uses some mechanisms to limit the rendering parameters defined in widgetMember variableIt has to befinalOf;

How does flutter make sure that the data defined in the widget is final?

Let’s take a look at the source code of widget

@immutable
abstract class Widget extends DiagnosticableTree {
    //... omit code
}

Here’s a key thing @ immutable

  • We don’t seem to have seen this syntax in dart, which is actually a problemannotationWe will not talk about the meta programming of dart;
  • Here I will explain what @ immutable is for;

In fact, @ immutable is officially explained:

The stateful widget of flutter (7)

ConclusionThe data defined in the widget must be immutable and need to be modified with final

1.1.2. How to store widget status?

Since widget is immutable, how can stateful widget store variable state?

  • Statelesswidget doesn’t matter, because the data in it is usually defined directly and will not be modified after playing.
  • But stateful widgets need to have state (which can be understood as variables) changes. How can this be done?

Flutter designs statefulwidget into two classes:

  • In other words, when you create a stateful widget, you must create two classes:
  • A class inherits from statefulwidget as a part of the widget tree;
  • A class inherits from state, which is used to record the changing state of stateful widget and build a new widget according to the change of state;

To create a stateful widget, we usually do it in the following format:

  • When flutter builds a widget tree, it getsInstance of stateAnd it calls the build method to get the widget that statefulwidget wants to build;
  • Then, we can save the state to be saved in mystate because it is changeable;
class MyStatefulWidget extends StatefulWidget {
  @override
  State<StatefulWidget> createState() {
    //Returns the created state to the
    return MyState();
  }
}

class MyState extends State<MyStatefulWidget> {
  @override
  Widget build(BuildContext context) {
    Return < build your own widget >;
  }
}

Thinking: why is flutter designed like this?

This is because in flutter, whenever the data changes, the widget needs to be rebuilt

1.2. Statefulwidget case

1.2.1. Case effect and analysis

Let’s practice stateful widget through a case, which is the previous counter case, but we make some improvements in our own way.

The case effect and layout are as follows:

  • In this case, there are many layouts that are a little complicated for us. We will learn them in detail later. I suggest you write them step by step according to my code to get familiar with the development mode of flutter;
  • Column widget: we have used it before. When there is a vertical layout, we use it;
  • Row widget: We used it before. We used it for horizontal layout;
  • Raisebutton widget: you can create a button with one of themOnpress propertiesIt’s an incoming oneCallback functionWhen the button is clicked, it will be called back;

The stateful widget of flutter (7)

1.2.2. Create statefulwidget

Let’s take a look at the code implementation

  • Because when we click the button, the number will change, so we need to use a stateful widget, so we need to create two classes;
  • Mycounterwidget inherits from statefulwidget, which needs to implement the createstate method;
  • Mycounterstate inherits from state, which implements the build method and defines some member variables;
class MyCounterWidget extends StatefulWidget {
  @override
  State<StatefulWidget> createState() {
    //Returns the created state to the
    return MyCounterState();
  }
}

class MyCounterState extends State<MyCounterWidget> {
  int counter = 0;

  @override
  Widget build(BuildContext context) {
    return Center(
      Child: text ("current count: $counter", style: TextStyle (fontsize: 30),),
    );
  }
}

The stateful widget of flutter (7)

1.2.3. Realize the layout of buttons

class MyCounterState extends State<MyCounterWidget> {
  int counter = 0;

  @override
  Widget build(BuildContext context) {
    return Center(
      child: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: <Widget>[
          Row(
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              RaisedButton(
                color: Colors.redAccent,
                child: Text("+1", style: TextStyle(fontSize: 18, color: Colors.white),),
                onPressed: () {

                },
              ),
              RaisedButton(
                color: Colors.orangeAccent,
                child: Text("-1", style: TextStyle(fontSize: 18, color: Colors.white),),
                onPressed: () {

                },
              )
            ],
          ),
          Text ("current count: $counter", style: TextStyle (fontsize: 30),)
        ],
      ),
    );
  }
}

The stateful widget of flutter (7)

1.2.4. Button click status change

Now we need to monitor the change of state and modify it when the state changesCounter variable

  • But can changing variables directly change the interface? may not.
  • This is because flutter doesn’t know that our data has changed and needs to rebuild the widget in our interface;

How can we let flutter know that our state has changed and rebuild our widget?

  • We need to call a set state method provided to us by default in a state;
  • We can modify our variables in the callback function;
onPressed: () {
  setState(() {
    counter++;
  });
},

In this way, the desired effect can be achieved

The stateful widget of flutter (7)

1.3. Statefulwidget lifecycle

1.3.1. Understanding of life cycle

What is life cycle?

  • Client development: in IOS development, we need to know the whole process of uiviewcontroller from creation to destruction, and in Android development, we need to know the whole process of activity from creation to destruction. In order to complete different operations in different life cycle methods;
  • In front-end development: Vue, react development components also have their own life cycle, in different life cycle we can do different operations;

Life cycle of the flutter widget:

  • Statelesswidget can pass in the value directly from the parent widget and call the build method to build it. The whole process is very simple;
  • Stateful widget needs to manage its data through state and monitor the change of state to decide whether to rebuild the whole widget;
  • Therefore, we mainly discuss the life cycle of stateful widget, that is, the whole process from creation to destruction;

1.3.2. Simple version of life cycle

In this version, I will explain the common methods and callbacks. In the next version, I will explain some more complex methods and callbacks

So what are the lifecycle callbacks of statefulwidget? Under what circumstances are they executed?

  • In the figure below, the gray parts are operated inside the flutter, so we don’t need to set them manually;
  • The white part indicates the method that we can listen to or call manually;

We know that statefulwidget itself consists of two classes:StatefulWidgetandStateWe analyzed them separately

The stateful widget of flutter (7)

First, executionStatefulWidgetMethods in this paper

  • 1. Execute the constructor of statefulwidget to create statefulwidget;
  • 2. Execute the createstate method of statefulwidget to create a state object that maintains statefulwidget;

Secondly, when calling createstate to create a state object, execute the related methods of the state class

  • 1. Execute the constructor of the state class to create the state object;
  • 2. When executing initstate, we usually perform some data initialization operations in this method, or we may send network requests;

    • Note: this method is to override the method of the parent class. You must call super, because some other operations will be performed in the parent class;
    • And if you read the source code, you will find an annotation here: @ mustcallsuper

The stateful widget of flutter (7)

  • 3. Execute the didchangedependencies method, which is called in two cases
    • Case 1: calling initstate will call;
    • Case 2: when the dependency on some data from other objects changes, such as the inherited widget (which will be discussed later);
  • 4. Flutter executes the build method to see which widgets our current widget needs to render;
  • 5. When the current widget is no longer in use, dispose will be called to destroy it;
  • 6. If you call the setstate method manually, you will call the build method again according to the latest state (data) to build the corresponding widgets;
  • 7. When executing the didupdatewidget method, the system will call the didupdatewidget method when the parent widget triggers rebuild;

Let’s demonstrate through the code:

import 'package:flutter/material.dart';

main(List<String> args) {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text("HelloWorld"),
        ),
        body: HomeBody(),
      ),
    );
  }
}


class HomeBody extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    print("HomeBody build");
    return MyCounterWidget();
  }
}


class MyCounterWidget extends StatefulWidget {
  
  MyCounterWidget() {
    Print ("executed the construction method of mycounterwidget");
  }
  
  @override
  State<StatefulWidget> createState() {
    Print ("the createstate method of mycounterwidget is executed");
    //Returns the created state to the
    return MyCounterState();
  }
}

class MyCounterState extends State<MyCounterWidget> {
  int counter = 0;
  
  MyCounterState() {
    Print ("execute the construction method of mycounterstate");
  }

  @override
  void initState() {
    super.initState();
    Print ("execute the init method of mycounterstate");
  }
  
  @override
  void didChangeDependencies() {
    // TODO: implement didChangeDependencies
    super.didChangeDependencies();
    Print ("execute the didchangedependencies method of mycounterstate");
  }

  @override
  Widget build(BuildContext context) {
    Print ("execute the build method of mycounterstate");
    return Center(
      child: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: <Widget>[
          Row(
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              RaisedButton(
                color: Colors.redAccent,
                child: Text("+1", style: TextStyle(fontSize: 18, color: Colors.white),),
                onPressed: () {
                  setState(() {
                    counter++;
                  });
                },
              ),
              RaisedButton(
                color: Colors.orangeAccent,
                child: Text("-1", style: TextStyle(fontSize: 18, color: Colors.white),),
                onPressed: () {
                  setState(() {
                    counter--;
                  });
                },
              )
            ],
          ),
          Text ("current count: $counter", style: TextStyle (fontsize: 30),)
        ],
      ),
    );
  }

  @override
  void didUpdateWidget(MyCounterWidget oldWidget) {
    super.didUpdateWidget(oldWidget);
    Print ("execute the didupdatewidget method of mycounterstate");
  }

  @override
  void dispose() {
    super.dispose();
    Print ("execute the dispose method of mycounterstate");
  }
}

The print results are as follows:

flutter: HomeBody build
Flutter: implemented the construction method of mycounterwidget
Flutter: the createstate method of mycounterwidget is executed
Flutter: the construction method of executing mycounterstate
Flutter: execute init method of mycounterstate
Flutter: execute the didchangedependencies method of mycounterstate
Flutter: execute the build method of mycounterstate

//Note: flutter will build all components twice (check GitHub and stack overflow, but no reason is found at present)
flutter: HomeBody build
Flutter: implemented the construction method of mycounterwidget
Flutter: execute the didupdatewidget method of mycounterstate
Flutter: execute the build method of mycounterstate

When we change the state, the following results will be printed after manually executing the setstate method:

Flutter: execute the build method of mycounterstate

1.3.3. Complex version of life cycle

Let’s learn a few of the attributes mentioned in the previous life cycle diagram, but they are not explained in detail

1. Mounted is an attribute set inside a state. In fact, we can do without understanding it. But if you want to have a deeper understanding of it, you will have a clearer understanding of the mechanism of state;

  • Many materials do not mention this property, but I list it here. It is set internally and does not need to be modified manually;

The stateful widget of flutter (7)

2. Dirty state means dirty state

  • It is actually marked by the attribute of an element (we haven’t talked about the principle of flutter drawing yet);
  • Marking it as dirty will wait for the next redraw check and force the build method to build our widget;
  • (I have the opportunity to write a special article about the difference between statelesswidget and stateful widget, and explain some of the selection problems in their development.);

3. Clean state means clean state

  • It represents the widget that is currently built and does not need to be rebuilt in the next redraw check;

2、 The programming paradigm of flutter

This chapter also explains some theoretical things. It may not directly teach the knowledge of flutter, but it will have some simple ideas for you to write any code in the future;

2.1. Understanding of programming paradigm

Programming paradigmFor beginners of programming, it is an illusory thing, but it is what we follow by default in our daily developmentSome models and methods

For example, we are most familiar withobject-oriented programmingIt is a kind of programming paradigm, which includes process oriented programming, functional programming and protocol oriented programming;

In addition, there are two corresponding programming paradigmsImperative programmingandDeclarative programming

  • Command programming:Imperative programming is very easy to understand, that is, giving the computer commands step by step to tell it what we want to do;
  • Declarative programming:Declarative programming usually describes the nature of the target, what you should be and what states you depend on. When the state of the dependency changes, we inform the target to make corresponding decisions in some ways;

The above description is too general. Let’s take a look at some specific examples;

2.2. Front end programming paradigm

The following code has not written the front-end, you can take a simple look

The following code is the two demos I wrote in the front-end development, both of which are used to modify the content of H2 tag after clicking the button:

  • Code on the left:Command programming, step by step to tell the browser what I want to do;
  • Code on the right:Declarative programming, I just tell H2 tag that I need to display the title. When the title changes, some mechanisms will automatically update the status;

The stateful widget of flutter (7)

2.3. The programming paradigm of flutter

Declarative programming has been popular since 2009 (data from Wikipedia), and now it is used in Vue, react, swiftui including IOS and flutter.

Now let’s develop a requirement: display a hello world, and then modify it to Hello flutter

If it’s traditional imperative programming, the mode we develop flutter is likely to be like this: (note the imaginary pseudo code)

  • In the whole process, we need to tell flutter what it needs to do step by step;
final text = new Text();
var title = "Hello World";
text.setContent(title);

//Modify data
title = "Hello Flutter";
text.setContent(title);

For declarative programming, we usually maintain a set of data sets:

  • This data set may come from its own parent class, from its own state management, from inherited widget, and from the place of unified state management;
  • In short, we know that there is such a data set and tell flutter where to use it;
var title = "Hello World";

Text (title); // tell text that the internal display is title

//Data change
title = "Hello Flutter";
Setstate (() = > null); // notify to rebuild widget

The above code is too simple, which may not reflect the advantages of fluent declarative programming. However, in the future development, we all start according to this mode. Let’s experience it together;

Note: all contents start with the official account. After that, Flutter will update other technical articles. TypeScript, React, Node, uniapp, mpvue, data structure and algorithm will also update some of their learning experiences. Welcome everyone’s attention.

The stateful widget of flutter (7)

Recommended Today

C # regular implementation of UBB parsing class code

The parsed code can pass XHTML   one   Strict verification;It includes title, link, font, alignment, picture, reference, list and other functions  Ubb.ReadMe.htm UBB code description title [H1] title I [/ H1] Title I [H2] Title II [/ H2] Title II [H1] Title III [/ H1] Title III [H4] Title IV [/ H4] Title IV […]