
StatefulWidget

/**
* 需求:
* 两个按钮,一个计数器
* 这里要用到 StatefulWidget,因为 StatelessWidget 通常用来展示固定不变的数据
*/
main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: MyHomeContent(),
);
}
}
/**
* Widget 中的数据都是不可变的,为何必须定义为 final ?
* 因为 Widget 中展示的数据发生变化时辉重新构建整个 Widget
* Widget 源码中有 @immutable 注解,(被@immutable注解标明的类或者子类都必须是不可变的)
*
* Flutter 将 StatefulWidget 设计成了两个类,创建 StatefulWidget 时必须创建两个类:
* 1 一个类继承自 StatefulWidget,作为 Widget树的一部分
* 2 一个类继承自 State,用于记录 StatefulWidget 会变化的状态,并且根据状态的变化,构建出新的 Widget
*/
class MyHomeContent extends StatefulWidget {
@override
State<MyHomeContent> createState() => _MyHomeContentState();
}
class _MyHomeContentState extends State<MyHomeContent> {
var num = 0;
@override
Widget build(BuildContext context) {
return Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
'计数:$num',
style: TextStyle(fontSize: 28,color: Colors.blue,decoration: TextDecoration.none)
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
ElevatedButton(onPressed: (){
setState(() {
num++;
});
}, child: Icon(Icons.add)),
ElevatedButton(onPressed: (){
setState(() {
num--;
});
}, child: Icon(Icons.remove))
],
)
],
),
);
}
}
生命周期
main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: MyStatefulWidget(),
);
}
}
class MyStatefulWidget extends StatefulWidget {
MyHomeContent(){
print('生命周期 ---- MyStatefulWidget的构造方法');
}
/**
* 当 Flutter 构建一个 StatefulWidget 时,会立即调用 createState() 方法。
* 这个方法返回一个 State 对象,该对象将管理这个 Widget 的状态。
*/
@override
State<MyStatefulWidget> createState() => _MyNumState();
}
class _MyNumState extends State<MyStatefulWidget> {
_MyNumState(){
print('生命周期 ---- _MyNumState的构造方法');
}
/**
* initState() 是 State 对象的初始化方法,只会被调用一次。
* 通常在这里进行一些初始化操作,比如订阅流、初始化数据等。
*/
@override
void initState() {
super.initState();
print('生命周期 ---- _MyNumState的 init方法');
}
/**
* didChangeDependencies() 在 initState() 之后立即调用,
* 并且在依赖的 InheritedWidget 发生变化时也会调用。
* 通常在这里执行一些依赖于 BuildContext 或 InheritedWidget 的操作。
*/
@override
void didChangeDependencies() {
super.didChangeDependencies();
print('生命周期 ---- _MyNumState的 didChangeDependencies方法');
}
/**
* build() 方法是构建 Widget 树的核心方法,每次 UI 需要更新时都会调用。
* 这个方法必须返回一个 Widget,通常是组合其他 Widget 来构建界面。
*/
@override
Widget build(BuildContext context) {
print('生命周期 ---- _MyNumState的 build方法');
return Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Row(
children: [
ElevatedButton(onPressed: (){
/**
* setState() 用于通知 Flutter 框架状态已经改变,需要重新构建 UI。
* 调用 setState() 会触发 build() 方法。
*/
setState(() {
});
}, child: Icon(Icons.remove))
],
)
],
),
);
}
/**
* 当父 Widget 重建并传入新的 Widget 配置时,didUpdateWidget() 会被调用。
* 通常在这里比较新旧 Widget 的配置,并根据需要更新状态。
*/
@override
void didUpdateWidget(covariant MyStatefulWidget oldWidget) {
super.didUpdateWidget(oldWidget);
print('生命周期 ---- _MyNumState的 didUpdateWidget方法');
}
/**
* 当 State 对象从 Widget 树中移除时,deactivate() 会被调用。
* 通常在这里做一些清理工作,但 State 对象仍然可能被重新插入到树中。
*/
@override
void deactivate() {
super.deactivate();
print('生命周期 ---- _MyNumState的 deactivate方法');
}
/**
* 当 State 对象从 Widget 树中永久移除时,dispose() 会被调用。
* 通常在这里释放资源,比如取消订阅、关闭流等。
*/
@override
void dispose() {
super.dispose();
print('生命周期 ---- _MyNumState的 dispose方法');
}
}