🔄 状态组件详解
状态管理是 Flutter 开发的核心概念。本页面将详细介绍各种状态组件和状态管理方案。
🎯 StatelessWidget
StatelessWidget 是无状态组件,其 UI 只依赖于传入的参数,不依赖内部状态。
基本用法
class MyTextWidget extends StatelessWidget {
final String text;
final Color color;
const MyTextWidget({
Key? key,
required this.text,
this.color = Colors.black,
}) : super(key: key);
@override
Widget build(BuildContext context) {
return Text(
text,
style: TextStyle(color: color),
);
}
}
使用场景
- 静态内容展示
- 纯 UI 组件
- 不涉及状态变化的场景
💡 提示:StatelessWidget 更轻量,性能更好,在不需要状态管理的场景下优先使用。
🔄 StatefulWidget
StatefulWidget 是有状态组件,可以维护内部状态,状态变化时会重新构建 UI。
基本用法
class CounterWidget extends StatefulWidget {
@override
_CounterWidgetState createState() => _CounterWidgetState();
}
class _CounterWidgetState extends State {
int _counter = 0;
void _increment() {
setState(() {
_counter++;
});
}
@override
Widget build(BuildContext context) {
return Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
'计数器: $_counter',
style: TextStyle(fontSize: 24),
),
SizedBox(height: 20),
ElevatedButton(
onPressed: _increment,
child: Text('增加'),
),
],
);
}
}
生命周期
- initState():组件初始化时调用
- build():构建 UI 时调用
- didUpdateWidget():父组件重建时调用
- setState():更新状态并重建 UI
- dispose():组件销毁时调用
💡 提示:使用 setState() 更新状态时,Flutter 会自动调用 build() 方法重新构建 UI。
📡 InheritedWidget
InheritedWidget 是用于在组件树中向下传递数据的组件,常用于状态管理。
基本用法
class CounterProvider extends InheritedWidget {
final int counter;
final VoidCallback increment;
const CounterProvider({
Key? key,
required this.counter,
required this.increment,
required Widget child,
}) : super(key: key, child: child);
static CounterProvider of(BuildContext context) {
return context.dependOnInheritedWidgetOfExactType()!;
}
@override
bool updateShouldNotify(CounterProvider oldWidget) {
return counter != oldWidget.counter;
}
}
// 使用示例
class CounterWidget extends StatelessWidget {
@override
Widget build(BuildContext context) {
final provider = CounterProvider.of(context);
return Column(
children: [
Text('计数器: ${provider.counter}'),
ElevatedButton(
onPressed: provider.increment,
child: Text('增加'),
),
],
);
}
}
使用场景
- 全局状态管理
- 主题管理
- 用户信息传递
💡 提示:InheritedWidget 是许多状态管理方案(如 Provider、Bloc)的基础。
⏳ FutureBuilder
FutureBuilder 用于根据 Future 的状态构建不同的 UI。
基本用法
FutureBuilder(
future: _fetchData(),
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return CircularProgressIndicator();
} else if (snapshot.hasError) {
return Text('错误: ${snapshot.error}');
} else if (snapshot.hasData) {
return Text('数据: ${snapshot.data}');
} else {
return Text('无数据');
}
},
)
Future _fetchData() async {
await Future.delayed(Duration(seconds: 2));
return '获取的数据';
}
状态类型
- none:Future 未开始
- waiting:正在等待结果
- active:正在执行
- done:已完成
💡 提示:FutureBuilder 适用于一次性异步操作,如网络请求、文件读取等。
📡 StreamBuilder
StreamBuilder 用于根据 Stream 的数据流构建 UI,适用于持续的数据更新场景。
基本用法
StreamBuilder(
stream: _counterStream,
builder: (context, snapshot) {
if (snapshot.hasError) {
return Text('错误: ${snapshot.error}');
}
switch (snapshot.connectionState) {
case ConnectionState.none:
return Text('等待连接...');
case ConnectionState.waiting:
return CircularProgressIndicator();
case ConnectionState.active:
return Text('计数: ${snapshot.data}');
case ConnectionState.done:
return Text('流已结束');
}
},
)
Stream get _counterStream async* {
for (int i = 0; i < 10; i++) {
await Future.delayed(Duration(seconds: 1));
yield i;
}
}
使用场景
- 实时数据更新
- WebSocket 连接
- 用户输入监听
- 数据库查询
💡 提示:StreamBuilder 适用于持续的数据流,如实时聊天、股票价格等场景。