If the conditions of the choice are wrong, then the choice itself means nothing. ---- Zhang Fengjieteilie
The hardest part of life is making choices, especially when you can’t tell good from bad. To be, or not to be, that is a question
Your first choice in Flutter may be a StatelessWidget Or a StatefulWidget. In this article, I will tell you what these two widgets do, how they differ, and how to use them.
1. Formalization of description
The process by which a user opens an application until the end of the application process is called a session [1]. Visual elements, called display elements, such as a text, a button, an image... [2]. The set of all the properties of the display element is called [state], such as color, size, style... [3]. All states of a display element in a session are called [state set] [4]. A set of display elements seen by a user is called [interface] [5]. The set of all interfaces in a session is called [UI] [6]. Has change according to yuan state behavior is called [event] [7]. All of the events set in a session called [event set] : a display element during a session state set for the S, the collection element number definition: | S | said StatelessWidget as indicated by definition | S | = 1: StatefulWidget as indicated by | S | > 1Copy the code
Lemma 1: State (s) determines the behavior of the display element (w). Lemma 2: Events (e) can change the display element state (s). Each e corresponds to a state, which is called a mapping G, denoted as: S = G (e) corollary: W = F(g(e)). The synthetic mapping of F and G is denoted as f, then W = F(e).Copy the code
- StatelessWidget properties:
For any E, there is constant S, and there is constant W
- StatefulWidget properties:
The presence of e causes s to change
#define end
1.StatelessWidget : f(x) = 2
To display the following interface elements, select the StatelessWidget without any prerequisites
Below is an interface consisting of four display elements, each immutable once created
// Specify radius, whether to select, color, Class ShapeColor extends StatelessWidget {ShapeColor({Key Key, this.radius = 20, this.checked = true, this.color=Colors.red, this.shadowColor=Colors.blue, this.elevation=2}) : super(key: key); final double radius; // Radius final bool checked; // Final Color shadowColor; // Color final Color; // Color final double elevation; Build (BuildContext context) {var shape = Container(width: radius, height: radius, decoration: decoration); BoxDecoration(// circle decoration line color: color?? Colors.red, shape: BoxShape.circle, boxShadow: checked ? [BoxShadow(// shadowColor: shadowColor, offset: offset (0.0, 0.0), spreadRadius: elevation, blurRadius: elevation),] : [],),); return shape; }}Copy the code
2.StatefulWidget : g(x) = 2x
Just because a StatelessWidget itself is immutable doesn’t mean it can’t be changed from the outside
Just like f of x equals 2 is a constant horizontal line. No matter how hard x tries, he can’t get rid of the useless fate of 2. If I have a g of x equals 2x, then g of f of x is equal to 4x. This is where f (x) and g(x) collaborate to complete the 4x StatefulWidget. It’s like this g-map. You don’t have a stage, I give you, you can use your value.
class ShapeColorRadio extends StatefulWidget { ShapeColorRadio({Key key,this.radius = 20, this.color=Colors.red, this.shadowColor=Colors.blue, this.elevation=2}):super(key:key); final double radius; // radius final Color shadowColor; // Color final Color; // Color final double elevation; // color @override _ShapeColorRadioState createState() => _ShapeColorRadioState(); } class _ShapeColorRadioState extends State<ShapeColorRadio> { var _checked =false; @override Widget Build (BuildContext context) {return GestureDetector(onTap: (){setState(() {// Change state _checked=! _checked; }); }, child: ShapeColor( color: widget.color, elevation: widget.elevation, shadowColor: widget.shadowColor, radius: widget.radius, checked: _checked, ), ); }}Copy the code
3. How to choose
If you had realized from the beginning that what you needed was g(x) = 4x, you could have done it all at once. But the underlying logic is the same.
It’s like when you eat strawberry cake, you can eat it all in one mouthful, or you can eat the strawberry and the cake separately, and it all ends up in your stomach. Easy to swallow in one gulp, you can enjoy the taste, aftertaste and reuse of strawberries separately.
class ShapeColorRadio extends StatefulWidget { ShapeColorRadio({Key key,this.radius = 20, this.color=Colors.red, this.shadowColor=Colors.blue, this.elevation=2}):super(key:key); final double radius; // radius final Color shadowColor; // Color final Color; // Color final double elevation; // color @override _ShapeColorRadioState createState() => _ShapeColorRadioState(); } class _ShapeColorRadioState extends State<ShapeColorRadio> { var _checked =false; @override Widget build(BuildContext context) { var shape = Container( width: widget.radius, height: Widget. radius, decoration: BoxDecoration(// color: widget.color?? Colors.red, shape: BoxShape.circle, boxShadow: _checked ? [BoxShadow(// shadowColor: widget.shadowColor, offset: offset (0.0, 0.0), spreadRadius: widget.elevation, blurRadius: widget.elevation ), ] : [], ), ); Return GestureDetector(onTap: (){setState(() {// Change state _checked=! _checked; }); }, child: shape, ); }}Copy the code
4. Unique advantages of StatefulWidget
StatefulWidget advantages is that it has a life cycle, initState, didChangeDependencies, didUpdateWidget, reassemble, build, deactivate, dispose. Each method is called back to the corresponding state of the component, making the StatefulWidget look more like a living thing and the StatelessWidget more like a dead doll. If you want more fine-grained control of a component, StatefulWidget is your best bet.
If you write a field in your Widget that is not final, it will not crash, but AS will complain:
“TM, to say that we never change immutable, you are not final means several things.” Scared me into adding final immediately.
But what about fields that do need to be changed sometimes? One word: Use StatefulWidget What if you want to release an object when a component is removed: One word: Use StatefulWidget
What is used with StatelessWidget. f(x) = 2
Abuse StatefulWidget- Be as smart as you are
Some people say, well, if statefulWidgets are so good, why don’t I just use them all? “I asked. Let’s say the line f of x is equal to 2. Would you use f(x) = g(1) where g(x) = 2x?
If not, sort your trash. If that’s okay with you, fine. Littering is not my penalty. The energy transfer efficiency in the food chain is decreasing, and as long as there is transfer, there is loss.
abstract class StatelessWidget extends Widget {
const StatelessWidget({ Key key }) : super(key: key);
@override
StatelessElement createElement() => StatelessElement(this);
considerations.
@protected
Widget build(BuildContext context);
}
abstract class StatefulWidget extends Widget {
const StatefulWidget({ Key key }) : super(key: key);
@override
StatefulElement createElement() => StatefulElement(this);
@protected
State createState();
}
Copy the code
StatelessWidget relies on StatelessElement to create elements, and StatefulElement relies on StatefulElement to create elements. They have a common father named ComponentElement, and a grandfather named Element. So they are brothers, so if they have the same father, why are they so different? See what happens next.
Full of absurd words, a bitter tears. All the authors are crazy, who solve the taste.
This is the end of this article. If you want to taste Flutter quickly, Flutter For Seven days is a must-have. If you want to explore it, follow in my footsteps and complete a Flutter tour. In addition, I have a Flutter wechat communication group. You are welcome to join and discuss Flutter issues together. My wechat account is ZDL1994328.