题目
Flutter中有状态小部件(StatefulWidget)的基本结构
信息
- 类型:问答
- 难度:⭐
考点
StatefulWidget, State类, 生命周期
快速回答
创建StatefulWidget需要两个类:
- 继承
StatefulWidget的类(不可变) - 继承
State<T>的关联状态类(可变)
关键步骤:
- 在Widget类中重写
createState() - 在State类中重写
build()方法 - 使用
setState()更新UI
1. 基本结构示例
// 1. Widget类(不可变)
class MyCounter extends StatefulWidget {
const MyCounter({super.key});
@override
State<MyCounter> createState() => _MyCounterState();
}
// 2. State类(可变)
class _MyCounterState extends State<MyCounter> {
int _count = 0; // 可变状态变量
void _increment() {
setState(() { // 触发重建
_count++;
});
}
@override
Widget build(BuildContext context) {
return Column(
children: [
Text('Count: $_count'),
ElevatedButton(
onPressed: _increment,
child: const Text('+1'),
),
],
);
}
}
2. 核心原理
- 分离设计:StatefulWidget本身不可变,可变状态存储在独立的State对象中
- 生命周期:
createState():创建State对象(仅调用一次)initState():State初始化(可添加监听)build():构建UI(调用频率最高)dispose():销毁State(需清理资源)
- setState机制:标记状态变化,触发
build()方法重建UI
3. 最佳实践
- State类名使用下划线前缀(如
_MyCounterState)表示私有 - 状态变量用
_开头标记私有(如_count) - 在
initState()中初始化依赖:@override void initState() { super.initState(); _controller = AnimationController(vsync: this); } - 在
dispose()中释放资源:@override void dispose() { _controller.dispose(); // 防止内存泄漏 super.dispose(); }
4. 常见错误
- 忘记调用
super:在initState()/dispose()中必须调用父类方法 - 直接修改状态:
// 错误!不会更新UI void _increment() { _count++; // 缺少setState } // 正确方式 void _increment() { setState(() => _count++); } - 在build()中修改状态:会导致无限重建循环
5. 扩展知识
- 状态管理进阶:当状态需要跨组件共享时,考虑使用Provider/Riverpod等方案
- const优化:尽可能使用StatelessWidget和const构造函数提升性能
- 生命周期全貌:
didChangeDependencies():依赖变化时调用didUpdateWidget():父组件重建时比较新旧配置