Flutter异步状态管理插件async_state_builder的使用
Flutter 异步状态管理插件 async_state_builder 的使用
async_state_builder
提供了轻量级的小部件来使用状态机和模式匹配处理异步数据。这个包是标准 StreamBuilder
和 FutureBuilder
小部件的一个改进版本,使得管理和响应异步计算的各种状态变得更加容易。
使用状态机的好处
使用状态机而不是在 StreamBuilder
/FutureBuilder
中使用的传统条件逻辑有几个优点:
- 可读性:模式匹配提供了清晰简洁的方式来处理各种状态,使代码更易于阅读和理解。
- 可维护性:状态机将状态逻辑与用户界面分离,使代码更易于维护和扩展。
- 可靠性:明确定义的状态减少了遇到意外状态或转换的可能性,提高了代码的健壮性。
使用方法
StreamStateMachineBuilder
StreamStateMachineBuilder<int>(
stream: stream,
builder: (BuildContext context, StreamState<int> state) {
return switch (state) {
Waiting() => const Text('Waiting for data...'),
Data<int>(:final data) => Text('Data: $data'),
Closed<int>(:final data?) => Text('Closed, data received before closing: $data'),
Closed<int>() => const Text('Closed before any data was sent'),
StreamStateMachineError<int>(:final data?, :final error) => Text('Error, data received before error: $data. Error: $error'),
StreamStateMachineError<int>(:final error) => Text('Error received before any data was sent. Error: $error'),
};
},
),
你也可以只针对你关心的状态进行编程:
switch (state) {
Waiting() => const Text('Waiting for data...'),
Data<int>(:final data) => Text('Data: $data'),
_ => Text('Unexpected state'),
};
StreamStateBuilder
StreamStateBuilder<int>(
stream: stream,
builder: (BuildContext context, StreamState<int> state) {
return switch (state) {
Waiting() => const Text('Waiting for data...'),
Data<int>(:final data) => Text('Data: $data'),
StreamError<int>(:final error) => Text('Error: $error'),
};
},
),
FutureStateBuilder
FutureStateBuilder<int>(
future: future,
builder: (BuildContext context, FutureState<int> state) {
return switch (state) {
Waiting() => const Text('Waiting to finish...'),
Data<int>(:final data) => Text('Data: $data'),
FutureError<int>(:final error) => Text('Error: $error'),
};
},
)
完整示例
以下是一个完整的示例,展示了如何使用 StreamStateMachineBuilder
来管理异步数据流的状态。
import 'dart:async';
import 'package:async_state_builder/async_state_builder.dart';
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
[@override](/user/override)
Widget build(BuildContext context) {
return const MaterialApp(
home: CounterPage(),
);
}
}
class CounterPage extends StatefulWidget {
const CounterPage({super.key});
[@override](/user/override)
CounterPageState createState() => CounterPageState();
}
class CounterPageState extends State<CounterPage> {
StreamController<int> _counterController = StreamController<int>();
int _counter = 0;
bool _hasWaitedTooLong = false;
[@override](/user/override)
void initState() {
super.initState();
}
void _incrementCounter() {
_counter++;
_counterController.add(_counter);
}
void _closeStream() {
_counterController.close();
}
void _sendError() {
_counterController.addError('An error occurred!');
}
[@override](/user/override)
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('StreamStateBuilder example'),
),
body: _hasWaitedTooLong
? const Center(child: Text("Waited too long, callback invoked"))
: StreamStateMachineBuilder<int>(
stream: _counterController.stream,
waitingTimeoutAction:
WaitingTimeoutCallback(const Duration(seconds: 5), () {
setState(() {
_hasWaitedTooLong = true;
});
}),
builder:
(BuildContext context, StreamStateMachineState<int> state) {
return Center(
child: switch (state) {
Waiting() => const Text('Waiting for data...'),
StreamStateMachineError<int>(:final data?, :final error) =>
Text(
'Error, data received before error: $data. Error: $error'),
Closed<int>(:final data?) =>
Text('Closed, data received before closing: $data'),
Data<int>(:final data) =>
Text('Data sent without error: $data'),
StreamStateMachineError<int>(:final error) => Text(
'Error received before any data was sent. Error: $error'),
Closed<int>() =>
const Text('Stream closed, before any data was sent'),
});
},
),
floatingActionButton: Column(
mainAxisAlignment: MainAxisAlignment.end,
children: [
FloatingActionButton(
onPressed: () {
setState(() {
_counterController.close();
_counterController = StreamController();
_counter = 0;
_hasWaitedTooLong = false;
});
},
tooltip: 'Restart',
child: const Icon(Icons.refresh),
),
const SizedBox(height: 10),
FloatingActionButton(
onPressed: () {
setState(() {});
},
tooltip: 'Trigger rebuild',
child: const Icon(Icons.build),
),
const SizedBox(height: 10),
FloatingActionButton(
onPressed: _incrementCounter,
tooltip: 'Send Data',
child: const Icon(Icons.add),
),
const SizedBox(height: 10),
FloatingActionButton(
onPressed: _sendError,
tooltip: 'Send Error',
child: const Icon(Icons.error),
),
const SizedBox(height: 10),
FloatingActionButton(
onPressed: _closeStream,
tooltip: 'Close Stream',
backgroundColor: Colors.red,
child: const Icon(Icons.close),
),
],
),
);
}
}
更多关于Flutter异步状态管理插件async_state_builder的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter异步状态管理插件async_state_builder的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
当然,async_state_builder
是一个用于 Flutter 的异步状态管理插件,它简化了在 UI 中处理异步数据的工作流程。以下是一个如何使用 async_state_builder
的代码示例。
首先,确保在你的 pubspec.yaml
文件中添加依赖:
dependencies:
flutter:
sdk: flutter
async_state_builder: ^x.y.z # 请替换为最新版本号
然后运行 flutter pub get
以安装依赖。
下面是一个完整的 Flutter 应用示例,展示如何使用 async_state_builder
来管理异步状态:
import 'package:flutter/material.dart';
import 'package:async_state_builder/async_state_builder.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('Async State Builder Example'),
),
body: Center(
child: AsyncStateBuilder<String>(
future: _fetchData(),
builder: (context, state) {
if (state.isLoading) {
return CircularProgressIndicator();
} else if (state.hasError) {
return Text('Error: ${state.error}');
} else if (state.hasData) {
return Text('Data: ${state.data}');
} else {
// This state should not be reached if future is properly defined
return Text('No Data');
}
},
),
),
),
);
}
Future<String> _fetchData() async {
// Simulate a network request with a delay
await Future.delayed(Duration(seconds: 2));
return 'Hello, Flutter!';
}
}
在这个示例中,我们创建了一个简单的 Flutter 应用,它包含一个使用 AsyncStateBuilder
的 Scaffold
。AsyncStateBuilder
接受一个 future
和一个 builder
函数。
future
是一个返回异步数据的Future
。builder
函数根据AsyncState
的不同状态(加载中、有错误、有数据)返回不同的 UI。
_fetchData
函数模拟了一个网络请求,使用 Future.delayed
来模拟延迟。
当 AsyncStateBuilder
开始构建时,它首先显示一个 CircularProgressIndicator
,因为 future
还没有完成。2 秒后,future
完成,AsyncStateBuilder
显示获取到的数据。如果 future
过程中发生错误,它会显示错误信息。
这个示例展示了如何使用 async_state_builder
插件来简化异步状态管理,使代码更加简洁和易于维护。