持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第27天,点击查看活动详情
关于 StatefulWidget
StatefulWidget
在实际开发中,StatelessWidget 通常用来描述 UI 展示中状态固定的组件。如果 状态会发生改变,则需要使用 StatefulWidget 来描述
为什么 StatefulWidget 可以用来描述状态变化的组件?
源码展示
abstract class StatefulWidget extends Widget {
const StatefulWidget({ Key? key }) : super(key: key);
@override
StatefulElement createElement() => StatefulElement(this);
@protected
@factory
State createState();
}
StatefulWidget 继承自 Widget,Widget 是不可变的,所以 StatefulWidget 也不能定义状态。但是在 StatefulWidget 源码中可以发现,在 StatefulWidget 的初始化中,必须实现 createState() 这个方法,这个方法返回一个 State 对象,这个对象用于记录 StatefulWidget 会变化的状态,并且根据状态的变化,构建出新的 Widget
// 定义 StatefulWidget 子类
class HomeContent extends StatefulWidget {
const HomeContent({Key? key}) : super(key: key);
// 重写 createState 方法
@override
State<StatefulWidget> createState() {
// 创建 State 对象并返回
return _HomeContentState();
}
}
// 定义 State 子类
class _HomeContentState extends State<StatefulWidget> {
@override
Widget build(BuildContext context) {
// 构建自己的 Widget
return const Text("dart");
}
}
为什么 StatefulWidget 的 build() 方法放在 State 中
在构建 Widget 树时,会获取 State 的对象,并且该对象会调用 build() 方法去获取 StatefulWidget 希望构建的 Widget。在 Flutter 运行过程中,Widget 会被不断的创建和销毁,在状态改变时,State 并不会重新被创建,只是将需要保存的状态保存在 HomeContentState 中
示例展示
需求:通过 StatefulWidget 实现一个计数器
void main() {
runApp(const MyAPP());
}
class MyAPP extends StatelessWidget {
const MyAPP({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return const MaterialApp(
home:HomePage(),
);
}
}
class HomePage extends StatelessWidget {
const HomePage({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text("计算器"),
),
body: const HomeContent(),
);
}
}
class HomeContent extends StatefulWidget {
const HomeContent({Key? key}) : super(key: key);
@override
State<StatefulWidget> createState() {
return _HomeContentState();
}
}
class _HomeContentState extends State<StatefulWidget> {
int _value = 0;
@override
Widget build(BuildContext context) {
return Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
_getRowButtons(),
Text("结果是: $_value",style: const TextStyle(fontSize: 30))
],
)
);
}
Widget _getRowButtons () {
return Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
ElevatedButton(
onPressed: (){
_value++;
// 调用 setState 刷新状态
setState(() {
// 写在外面和里面是一样的,如果写在里面,在源码中 setState 也会调用该回调方法
//_value++;
});
},
style: ElevatedButton.styleFrom(primary: Colors.orange),
child: const Text("+",style: TextStyle(fontSize: 20))
),
ElevatedButton(
onPressed: (){
_value--;
setState(() {
});
},
style: ElevatedButton.styleFrom(primary: Colors.red),
child: const Text("-",style: TextStyle(fontSize: 20))
)
],
);
}
}
示例效果