Flutter异步阶段通知插件async_phase_notifier的使用
Flutter异步阶段通知插件async_phase_notifier
的使用
async_phase_notifier
是一个基于 ValueNotifier
的变种,用于表示异步操作的初始、等待、完成或错误阶段。它类似于 Riverpod 中的 AsyncNotifier
和 AsyncValue
,但与 Riverpod 没有绑定关系。
样例应用
- Useless Facts - 简单示例
- pub.dev 探索者 - 高级示例
使用方法
更新方法 update()
AsyncPhaseNotifier
的 update()
方法执行一个异步函数,并根据异步操作的阶段自动更新 AsyncPhaseNotifier
的值,同时通知监听器。
- 当操作开始时,通知器的值切换到
AsyncWaiting
。 - 通知监听器。
- 根据结果,值切换到
AsyncComplete
或AsyncError
。 - 通知监听器。
final notifier = AsyncPhaseNotifier(0);
notifier.update(() => someAsyncOperation());
更新仅限于阶段 updateOnlyPhase()
该方法与 update()
类似,但只更新阶段而不更新 value.data
。此方法适用于在执行过程中需要更新阶段,但回调结果不应影响数据的情况。
notifier.updateOnlyPhase(() => someAsyncOperation());
异步阶段 AsyncPhase
AsyncPhaseNotifier
的值可以是 AsyncInitial
、AsyncWaiting
、AsyncComplete
或 AsyncError
。这些类型都是 AsyncPhase
的子类型。
AsyncPhase
提供了 when()
和 whenOrNull()
方法,可用于根据当前阶段选择相应的操作。
child: phase.when(
initial: (data) => Text('phase: AsyncInitial($data)'), // 可选
waiting: (data) => Text('phase: AsyncWaiting($data)'),
complete: (data) => Text('phase: AsyncComplete($data)'),
error: (data, error, stackTrace) => Text('phase: AsyncError($data, $error)'),
)
value.data
与 data
data
是 value.data
的便捷获取器。如果 AsyncPhaseNotifier<T>
的泛型类型 T
是非空的,则返回类型也是非空的,这使得代码更安全。
监听阶段变化
listen()
通过 listen()
方法可以在阶段或其数据发生变化时触发某些动作。
final notifier = AsyncPhaseNotifier(Auth());
final cancel = notifier.listen((phase) { /* 一些动作 */ });
...
// 如果不再需要监听器,则移除它。
cancel();
listenFor()
通过 listenFor()
方法可以在阶段或其数据发生变化时触发某些动作。
final notifier = AsyncPhaseNotifier(Auth());
final cancel = notifier.listenFor(
onWaiting: (isWaiting) { /* e.g. 切换指示器 */ },
onComplete: (data) { /* e.g. 记录操作结果 */ },
onError: (e, s) { /* e.g. 显示错误对话框 */ },
);
...
// 如果不再需要监听器,则移除它。
cancel();
AsyncPhaseListener
还可以使用 AsyncPhaseListener
小部件来监听阶段变化。
child: AsyncPhaseListener(
notifier: notifier,
onWaiting: (isWaiting) { /* e.g. 切换指示器 */ },
onComplete: (data) { /* e.g. 记录操作结果 */ },
onError: (e, s) { /* e.g. 显示错误对话框 */ },
child: ...,
)
示例
下面是一个 WeatherNotifier
示例,它继承自 AsyncPhaseNotifier
并获取城市天气信息并通知其监听器。
class WeatherNotifier extends AsyncPhaseNotifier<Weather> {
WeatherNotifier() : super(const Weather());
final repository = WeatherRepository();
void fetch() {
update(() => repository.fetchWeather(Cities.tokyo));
}
}
final notifier = WeatherNotifier();
notifier.fetch();
使用 ValueListenableBuilder
[@override](/user/override)
Widget build(BuildContext context) {
return ValueListenableBuilder<AsyncPhase<Weather>>(
valueListenable: notifier,
builder: (context, phase, _) {
return phase.when(
waiting: (weather) => const CircularProgressIndicator(),
complete: (weather) => Text('$weather'),
error: (weather, e, s) => Text('$e'),
);
},
);
}
使用 Provider
ValueListenableProvider<AsyncPhase<Weather>>.value(
value: notifier,
child: MaterialApp(home: ...),
)
[@override](/user/override)
Widget build(BuildContext context) {
final phase = context.watch<AsyncPhase<Weather>>();
return phase.when(
waiting: (weather) => const CircularProgressIndicator(),
complete: (weather) => Text('$weather'),
error: (weather, e, s) => Text('$e'),
);
}
使用 Grab
void main() {
runApp(
const Grab(child: App()),
);
}
[@override](/user/override)
Widget build(BuildContext context) {
final phase = notifier.grab(context);
return phase.when(
waiting: (weather) => const CircularProgressIndicator(),
complete: (weather) => Text('$weather'),
error: (weather, e, s) => Text('$e'),
);
}
更多关于Flutter异步阶段通知插件async_phase_notifier的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter异步阶段通知插件async_phase_notifier的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
当然,关于Flutter中的async_phase_notifier
插件的使用,这里提供一个简单的代码示例来展示其基本用法。async_phase_notifier
允许你在异步操作的各个阶段发送通知,这对于长时间运行的任务尤其有用,你可以通知UI进行进度更新或显示加载指示器。
首先,确保你的pubspec.yaml
文件中已经添加了async_phase_notifier
依赖:
dependencies:
flutter:
sdk: flutter
async_phase_notifier: ^最新版本号 # 替换为实际的最新版本号
然后运行flutter pub get
来安装依赖。
下面是一个简单的例子,展示如何使用async_phase_notifier
来管理一个模拟的长时间异步任务,并在UI中更新进度。
main.dart
import 'package:flutter/material.dart';
import 'package:async_phase_notifier/async_phase_notifier.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('Async Phase Notifier Example'),
),
body: AsyncPhaseNotifierExample(),
),
);
}
}
class AsyncPhaseNotifierExample extends StatefulWidget {
@override
_AsyncPhaseNotifierExampleState createState() => _AsyncPhaseNotifierExampleState();
}
class _AsyncPhaseNotifierExampleState extends State<AsyncPhaseNotifierExample> {
final AsyncPhaseNotifier<int> _notifier = AsyncPhaseNotifier<int>();
@override
void initState() {
super.initState();
_startLongRunningTask();
}
void _startLongRunningTask() {
_notifier.start(
() async {
for (int i = 0; i <= 100; i += 10) {
await Future.delayed(Duration(seconds: 1)); // 模拟耗时操作
_notifier.notifyPhase(i);
}
_notifier.complete(100); // 完成最终阶段
},
onError: (error, stackTrace) {
// 处理错误
print('Error: $error');
},
);
}
@override
Widget build(BuildContext context) {
return Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
CircularProgressIndicator(
value: _notifier.progress ?? 0.0,
valueColor: AlwaysStoppedAnimation<Color>(Colors.blue),
),
SizedBox(height: 20),
Text(
'Progress: ${_notifier.progress?.toInt() ?? 0}%',
style: TextStyle(fontSize: 24),
),
],
);
}
@override
void dispose() {
_notifier.dispose(); // 清理资源
super.dispose();
}
}
解释
-
依赖安装:首先,在
pubspec.yaml
文件中添加async_phase_notifier
依赖。 -
创建应用:在
main.dart
中,创建一个简单的Flutter应用,其中包含一个AsyncPhaseNotifierExample
组件。 -
状态管理:在
_AsyncPhaseNotifierExampleState
中,使用AsyncPhaseNotifier<int>
来管理异步任务的状态和进度。 -
启动任务:在
initState
方法中,调用_startLongRunningTask
函数启动一个模拟的长时间异步任务。这个任务每隔一秒更新一次进度,并通过_notifier.notifyPhase(i)
发送进度通知。 -
UI更新:在
build
方法中,使用CircularProgressIndicator
和Text
组件来显示当前的进度。CircularProgressIndicator
的value
属性绑定到_notifier.progress
,从而根据进度更新UI。 -
资源清理:在
dispose
方法中调用_notifier.dispose()
来清理资源,避免内存泄漏。
这个示例展示了如何使用async_phase_notifier
来管理和通知异步操作的进度,从而更新UI。你可以根据自己的需求进一步定制和扩展这个示例。