主要区别
A StatelessWidget will never rebuild (unless bound to an InheritedWidget). A StatefulWidget can. That is the golden rule.
StatefulWidget可以重新构建,通过Widget的build方法,但是StatelessWidget只能重绘。
page的生命周期 参见:https://www.jianshu.com/p/05af657c13b0
详解
StatelessWidget
A stateless widget is a widget that describes part of the user interface by building a constellation of other widgets that describe the user interface more concretely. The building process continues recursively until the description of the user interface is fully concrete (e.g., consists entirely of RenderObjectWidgets, which describe concrete RenderObjects).
Stateless widget are useful when the part of the user interface you are describing does not depend on anything other than the configuration information in the object itself and the BuildContext in which the widget is inflated. For compositions that can change dynamically, e.g. due to having an internal clock-driven state, or depending on some system state, consider using StatefulWidget.
StatelfulWidget
A stateful widget is a widget that describes part of the user interface by building a constellation of other widgets that describe the user interface more concretely. The building process continues recursively until the description of the user interface is fully concrete (e.g., consists entirely of RenderObjectWidgets, which describe concrete RenderObjects).
Stateful widget are useful when the part of the user interface you are describing can change dynamically, e.g. due to having an internal clock-driven state, or depending on some system state. For compositions that depend only on the configuration information in the object itself and the BuildContext in which the widget is inflated, consider using StatelessWidget.
StatefulWidget instances themselves are immutable and store their mutable state either in separate State objects that are created by the createState method, or in objects to which that State subscribes, for example Stream or ChangeNotifier objects, to which references are stored in final fields on the StatefulWidget itself.
官方文档说明
...The important thing to note here is at the core both Stateless and Stateful widgets behave the same. They rebuild every frame, the difference is the StatefulWidget has a State object which stores state data across frames and restores it.
If you are in doubt, then always remember this rule: If a widget changes (the user interacts with it, for example) it’s stateful. However, if a child is reacting to change, the containing parent can still be a Stateless widget if the parent doesn’t react to change.
代码
StatelessWidget
我们想通过点击按钮实现屏幕输出'Flutter', 'is', 'cool', "and","awesome!",按一次按钮切换一次文字。先使用Stateless的方式实现一下 发现无论怎么点击,都无法改变屏幕的文字。
import 'package:flutter/material.dart';
void main() {
runApp(new MaterialApp(
home: new MyButton(),
));
}
class MyButton extends StatelessWidget {
int counter = 0;
List<String> strings = ['Flutter', 'is', 'cool', "and","awesome!"];
String displayedString = "Hello World!";
void onPressOfButton() {
displayedString = strings[counter];
counter = counter < 4 ? counter + 1 : 0;
}
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: new Text("Stateful Widget"),
backgroundColor: Colors.green,
),
body: new Container(
child: new Center(
child: new Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
new Text(displayedString, style: new TextStyle(fontSize: 40.0)),
new Padding(padding: new EdgeInsets.all(10.0)),
new RaisedButton(
child: new Text(
"Press me",
style: new TextStyle(color: Colors.white),
),
color: Colors.red,
onPressed: onPressOfButton,
)
],
),
),
),
);
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
我们在build函数设置断点,点击按钮,不会重新build。
StatelfulWidget
使用StatelfulWidget改造上面的代码。点击按钮,屏幕文字依次输出Flutter', 'is', 'cool', "and","awesome!"。
在这段代码中,我们创建了一个StatefulWidget对象MyButton, 重写了createState(),这个方法提供一个State类。
我们在build函数设置断点,点击按钮,点击按钮后会重新build。 程序调用栈如下:
import 'package:flutter/material.dart';
void main() {
runApp(new MaterialApp(
home: new MyButton(),
));
}
class MyButton extends StatefulWidget {
MyButtonState createState() {
return new MyButtonState();
}
}
class MyButtonState extends State<MyButton> {
int counter = 0;
List<String> strings = ['Flutter', 'is', 'cool', "and","awesome!"];
String displayedString = "Hello World!";
void onPressOfButton() {
setState(() {
displayedString = strings[counter];
counter = counter < 4 ? counter + 1 : 0;
});
}
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: new Text("Stateful Widget"),
backgroundColor: Colors.green,
),
body: new Container(
child: new Center(
child: new Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
new Text(displayedString, style: new TextStyle(fontSize: 40.0)),
new Padding(padding: new EdgeInsets.all(10.0)),
new RaisedButton(
child: new Text(
"Press me",
style: new TextStyle(color: Colors.white),
),
color: Colors.red,
onPressed: onPressOfButton,
)
],
),
),
),
);
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57