Flutter主流功能集成插件mainstream的使用
Flutter主流功能集成插件mainstream的使用
StreamBuilder
是 Flutter 中一个非常强大的小部件,它可以根据流(Stream)中的数据动态更新 UI。然而,StreamBuilder
并没有提供一种方法来接收流的 data
/error
/done
事件的回调。我们可能希望在这些事件发生时执行某些操作,例如更新 Navigator
。这在 StreamBuilder
的 builder
回调中实现是不可靠的,因为 Flutter 可能会多次调用 build()
方法。因此,我们需要额外的流监听器,但这需要创建一个 StatefulWidget
并取消流订阅。此外,如果我们的流不是广播流(意味着它不支持多个监听器),我们可能完全不能使用 StreamBuilder
。
问题
class Home extends StatefulWidget {
[@override](/user/override)
State<Home> createState() => _HomeState();
}
class _HomeState extends State<Home> {
StreamSubscription<FirebaseUser> _subscription;
[@override](/user/override)
void initState() {
super.initState();
_subscription = FirebaseAuth.instance.onAuthStateChanged.listen((event) {
Navigator.of(context).popUntil((route) => route.isFirst);
});
}
[@override](/user/override)
void dispose() {
_subscription.cancel();
super.dispose();
}
[@override](/user/override)
Widget build(BuildContext context) {
return StreamBuilder<FirebaseUser>(
stream: FirebaseAuth.instance.onAuthStateChanged,
builder: (_context, snapshot) => snapshot.data.isAnonymous ? LoggedOut() : LoggedIn(),
);
}
}
解决方案
MainStream
小部件使用了与 StreamBuilder
相同的基础 StreamBuilderBase
,但同时提供了额外的 onData
/onError
/onDone
回调。这些回调不会因小部件重建而重新触发。它还提供了构建器回调以构建互斥的 busy/data/error
小部件状态。
class Home extends StatelessWidget {
[@override](/user/override)
Widget build(BuildContext context) {
return MainStream<FirebaseUser>(
stream: FirebaseAuth.instance.onAuthStateChanged,
onData: (_) => Navigator.of(context).popUntil((r) => r.isFirst),
dataBuilder: (_, data) => data.isAnonymous ? LoggedOut() : LoggedIn(),
);
}
}
- 可以在
StatelessWidget
中使用。 - 支持单订阅和广播流。
- 提供了对传递给回调的数据的泛型类型安全。类型参数
<T>
可以省略,如果编译器可以推断出。
使用方法
final myStream = Stream<int>.periodic(Duration(seconds: 1), (x) => x).take(5);
class Home extends StatelessWidget {
[@override](/user/override)
Widget build(BuildContext context) {
return MainStream<int>(
stream: myStream,
onData: (data) => print(data),
onError: (error) => showDialog(...),
onDone: () => print('Done!'),
busyBuilder: (_) => CircularProgressIndicator(),
dataBuilder: (_, data) => Text(data.toString()),
errorBuilder: (_, error) => Text(error.toString()),
);
}
}
stream
参数是必需的。- 可选的
busyBuilder
显示一个小部件,当Stream
等待其第一个事件时。默认情况下,它显示一个居中的CircularProgressIndicator
。 - 可选的
dataBuilder
在Stream
的最后一个事件是一个成功的数据负载时显示一个小部件。Stream<T>
的结果T
值作为参数传递给回调。 - 可选的
errorBuilder
当Stream
的最后一个事件是一个错误时显示一个小部件,通常是一个Error
或Exception
。 - 可选的
onData
回调可用于处理成功数据事件,例如通过显示警报对话框或执行导航。这可以在dataBuilder
之外或与之一起使用。这不会因小部件重建而重新触发。 - 可选的
onError
回调可用于处理错误事件,例如通过显示警报对话框或将错误发送到日志记录提供程序。它可以单独使用或与errorBuilder
一起使用。这不会因小部件重建而重新触发。 - 可选的
onDone
回调可用于处理流的完成事件。这不会因小部件重建而重新触发。
示例代码
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:mainstream/mainstream.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
// 这个小部件是你的应用程序的根。
[@override](/user/override)
Widget build(BuildContext context) {
return MaterialApp(
home: Home(),
);
}
}
final myStream = Stream<int>.periodic(Duration(seconds: 1), (x) => (x == 3) ? throw Exception('oops') : x).take(5);
class Home extends StatelessWidget {
[@override](/user/override)
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: MainStream<int>(
stream: myStream,
onData: (data) => print(data),
onError: (error) => _showAlert(context, error.toString()),
onDone: () => print('Done!'),
busyBuilder: (_) => CircularProgressIndicator(),
dataBuilder: (_, data) => Text(data.toString()),
errorBuilder: (_, error) => Text(error.toString()),
),
),
);
}
void _showAlert(BuildContext context, String text) {
showDialog(
context: context,
builder: (_) {
return AlertDialog(
content: Text(text),
actions: <Widget>[
TextButton(
child: Text('OK'),
onPressed: () => Navigator.of(context).pop(),
)
],
);
},
);
}
}
更多关于Flutter主流功能集成插件mainstream的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html
1 回复