Flutter 异步UI更新(FutureBuilder、StreamBuilder)
封面图
•
2025-11-04
•
Flutter
0
0
0
0
在 Flutter 中,**异步 UI 更新**是开发中非常常见和重要的部分。Flutter 提供了两种主要的组件来处理异步数据并更新 UI:`FutureBuilder` 和 `StreamBuilder`。它们分别用于处理 **单次异步操作(如网络请求)** 和 **持续数据流(如实时更新、数据库监听)**。 --- ## 一、`FutureBuilder` ### ✅ 用途: 用于构建依赖于一个 `Future` 的 UI。当 `Future` 完成时,UI 会根据结果进行更新。 ### 📌 基本用法: ```dart Future<String> fetchUser() async { await Future.delayed(Duration(seconds: 2)); return "John Doe"; } @override Widget build(BuildContext context) { return FutureBuilder<String>( future: fetchUser(), builder: (context, snapshot) { if (snapshot.hasData) { return Text("Hello, ${snapshot.data}!"); } else if (snapshot.hasError) { return Text("${snapshot.error}"); } else { return CircularProgressIndicator(); } }, ); } ``` ### 🔍 参数说明: - `future`: 一个 `Future` 对象。 - `initialData`: 可选参数,设置初始数据(在 `snapshot.data` 中)。 - `builder`: 构建 UI 的回调函数,接受 `BuildContext` 和 `AsyncSnapshot<T>`。 ### 🧠 注意事项: - `snapshot.connectionState` 可以用来判断加载状态(如 `waiting`, `done`)。 - 如果 `Future` 已经完成,`builder` 会立即执行。 --- ## 二、`StreamBuilder` ### ✅ 用途: 用于构建依赖于一个 `Stream` 的 UI。适用于需要**持续更新**的数据源(如实时数据、数据库监听、传感器数据等)。 ### 📌 基本用法: ```dart Stream<int> counterStream() async* { int i = 0; while (true) { yield i++; await Future.delayed(Duration(seconds: 1)); } } @override Widget build(BuildContext context) { return StreamBuilder<int>( stream: counterStream(), initialData: 0, builder: (context, snapshot) { return Text("Count: ${snapshot.data}"); }, ); } ``` ### 🔍 参数说明: - `stream`: 一个 `Stream` 对象。 - `initialData`: 可选参数,初始数据。 - `builder`: 构建 UI 的回调函数,接受 `BuildContext` 和 `AsyncSnapshot<T>`。 ### 🧠 注意事项: - `StreamBuilder` 会在每次 `Stream` 发出新数据时重新构建 UI。 - 使用 `Stream.cancel()` 取消监听可以避免内存泄漏。 --- ## 三、`AsyncSnapshot` 的状态 无论是 `FutureBuilder` 还是 `StreamBuilder`,都会返回一个 `AsyncSnapshot<T>` 对象,它包含以下状态: | 状态 | 说明 | |------|------| | `ConnectionState.waiting` | 数据正在加载中(`Future` 未完成或 `Stream` 尚未发出数据) | | `ConnectionState.done` | 数据已加载完成(`Future` 完成或 `Stream` 结束) | | `snapshot.hasData` | 是否有数据 | | `snapshot.hasError` | 是否有错误 | --- ## 四、对比总结 | 特性 | `FutureBuilder` | `StreamBuilder` | |------|------------------|------------------| | 数据来源 | 单次异步操作(如 API 请求) | 持续数据流(如 WebSocket、数据库监听) | | 数据更新 | 一次或多次 | 多次(持续更新) | | 适用场景 | 加载数据后不再变化 | 实时数据、用户输入、位置更新等 | --- ## 五、示例:结合使用 `FutureBuilder` 和 `StreamBuilder` ```dart class MyPage extends StatelessWidget { @override Widget build(BuildContext context) { return Column( children: [ FutureBuilder<String>( future: fetchUser(), builder: (context, snapshot) { if (snapshot.hasData) { return Text("Welcome, ${snapshot.data}!"); } return CircularProgressIndicator(); }, ), StreamBuilder<int>( stream: counterStream(), initialData: 0, builder: (context, snapshot) { return Text("Counter: ${snapshot.data}"); }, ), ], ); } } ``` --- ## 六、最佳实践 - 使用 `FutureBuilder` 处理一次性数据加载。 - 使用 `StreamBuilder` 处理实时数据流。 - 避免在 `builder` 中执行耗时操作。 - 在 `dispose` 中取消 `Stream`,防止内存泄漏。 --- 如果你有具体的使用场景或问题,欢迎继续提问!
上一篇:
Flutter 按需rebuild(ValueListenableBuilder)
下一篇:
Flutter 对话框详解
标题录入,一次不能超过6条
留言
评论