Stream 流
Stream的字面意思是水流,Stream不像Future那样只会在未来获取一个值,它可以异步获取0个或者 多个值。如果说Future是一个异步版本的int或者String,Stream则更像是异步版本的列表,List,List, 列表里面可能会有0个或者多个元素。class MyHomePage extends StatefulWidget { const MyHomePage({super.key}); @override State<MyHomePage> createState() => _MyHomePageState(); } class _MyHomePageState extends State<MyHomePage> { Future<String> loadData() async { return "这是一个Flutter"; // 正常返回数据 } //定义一个异步流 Stream<int> loadDataStream() { return Stream.periodic(Duration(seconds: 1), (v) => v); } @override void initState() { super.initState(); // 获取异步方法的数据 loadData().then((value) => print(value)); //打印数据 //获取异步流的数据 loadDataStream().listen((event) { print("stream--------------------------:$event"); }); } @override Widget build(BuildContext context) { return const Center( child: Text("Text"), ); } }
StreamBuilder 局部数据更新
在 Flutter 中,StreamBuilder 是一个将 Stream 流与 Widget结合到一起的组件,可实现组件的局部数 据更新 , StreamBuilder 组件和FutureBuilder组件比较相似,不同点在于它是一个可以自动跟踪Stream (数据流或事件流)的状态,并在Stream有变化时自动重绘的组件。Stream不同于Future,可能会在 生命周期内释放出任意数量的数据值(正常)或者错误信息(异常),通常被用于读取文件或者下载网 络资源等操作,也有时候用于状态管理。 StreamBuilder主要功能:- 实现局部刷新
- 读取流实现读取文件或者下载网络资源等操作
- 父子组件之间的数据广播
class MyHomePage extends StatefulWidget { const MyHomePage({super.key}); @override State<MyHomePage> createState() => _MyHomePageState(); } class _MyHomePageState extends State<MyHomePage> { //定义一个异步流 Stream<int> loadDataStream() { return Stream.periodic(Duration(seconds: 1), (v) { if (Random().nextBool()) { //随机生成一个true或者false return v; } throw "这是一个异常"; }); } @override void initState() { super.initState(); //获取异步流的数据 loadDataStream().listen((event) { print("stream--------------------------:$event"); }); } @override Widget build(BuildContext context) { return Center( child: StreamBuilder( stream: loadDataStream(), //获取流 builder: (context, snapshot) { // 观察ConnectionState的状态 print(snapshot.connectionState); //获取状态 switch (snapshot.connectionState) { case ConnectionState.none: return const Center( child: Text("NONE: 没有数据流"), ); case ConnectionState.waiting: //等待中 return const Center(child: Text("WAITING: 等待数据流")); case ConnectionState.active: //正常运行状态 if (snapshot.hasError) { //隐藏 return Center( child: Text("ACTIVE: 数据流活跃,异常: ${snapshot.error}")); } else { return Center( child: Text("ACTIVE: 数据流活跃,数据: ${snapshot.data}")); } case ConnectionState.done: //结束 return const Center(child: Text("DONE: 数据流关闭")); default: throw "ConnectionState没有别的状态"; //抛异常 } }), ); } }
StreamController 异步数据流的监听、添加数据、关闭流等操作
创建更精确的数据流class DemoPage extends StatefulWidget { @override State<DemoPage> createState() => _DemoPageState(); } class _DemoPageState extends State<DemoPage> { // 定义一个类型为int的Stream final _controller = StreamController<int>(); @override void dispose() { super.dispose(); _controller.close(); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: const Text("Stream Demo"), ), body: Wrap( spacing: 20, children: [ ElevatedButton( // 按钮点击后Stream会释放出数字1 child: const Text("Emit 1"), onPressed: () => _controller.add(1), ), ElevatedButton( // 按钮点击后Stream会释放出数字2 child: const Text("Emit 2"), onPressed: () => _controller.add(2), ), ElevatedButton( // 按钮点击后Stream会释放出一个错误 child: const Text("Emit Error"), onPressed: () => _controller.addError("500 错误"), ), ElevatedButton( // 按钮点击后Stream会关闭 child: const Text("Close"), onPressed: () => _controller.close(), //关闭流 一般不手动关闭 ), StreamBuilder( stream: _controller.stream, builder: (context, snapshot) { print("正在重新绘制StreamBuilder组件…"); if (snapshot.connectionState == ConnectionState.done) { //判断流是否关闭 return const Text("数据流已关闭"); } if (snapshot.hasError) return Text("${snapshot.error}"); //流中有异常 if (snapshot.hasData) return Text("${snapshot.data}"); return const Center( child: CircularProgressIndicator(), //圈圈 ); }, ) ], ), ); } }
StreamController.broadcast() 多个监听者
StreamController 默认只能有一个监听这,如果有多个监听者的话就需要用 StreamController.broadcast()class DemoPage extends StatefulWidget { @override State<DemoPage> createState() => _DemoPageState(); } class _DemoPageState extends State<DemoPage> { //broadcast创建的流可以有多个监听者 final _controller = StreamController.broadcast(); @override void initState() { // TODO: implement initState super.initState(); _controller.stream.listen((event) { //监听 print("-----------------------------------$event"); }); } @override void dispose() { super.dispose(); _controller.close(); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: const Text("Stream Demo"), ), body: Wrap( spacing: 20, children: [ ElevatedButton( // 按钮点击后Stream会释放出数字1 child: const Text("Emit 1"), onPressed: () => _controller.add(1), ), ElevatedButton( // 按钮点击后Stream会释放出数字2 child: const Text("Emit 2"), onPressed: () => _controller.add(2), ), ElevatedButton( // 按钮点击后Stream会释放出一个错误 child: const Text("Emit Error"), onPressed: () => _controller.addError("oops"), ), ElevatedButton( // 按钮点击后Stream会关闭 child: const Text("Close"), onPressed: () => _controller.close(), ), StreamBuilder( stream: _controller.stream, // 去除重复的数据 builder: (context, snapshot) { print("正在重新绘制StreamBuilder组件…"); if (snapshot.connectionState == ConnectionState.done) { return const Text("数据流已关闭"); } if (snapshot.hasError) return Text("${snapshot.error}"); if (snapshot.hasData) return Text("${snapshot.data}"); return const Center( child: CircularProgressIndicator(), ); }, ) ], ), ); } }
Stream过滤
class DemoPage extends StatefulWidget { @override State<DemoPage> createState() => _DemoPageState(); } class _DemoPageState extends State<DemoPage> { // 定义一个类型为int的Stream final _controller = StreamController.broadcast(); @override void initState() { // TODO: implement initState super.initState(); _controller.stream.listen((event) { print(event); }); } @override void dispose() { super.dispose(); _controller.close(); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: const Text("Stream Demo"), ), body: Wrap( spacing: 20, children: [ ElevatedButton( // 按钮点击后Stream会释放出数字1 child: const Text("Emit 1"), onPressed: () => _controller.add(1), ), ElevatedButton( // 按钮点击后Stream会释放出数字2 child: const Text("Emit 2"), onPressed: () => _controller.add(2), ), ElevatedButton( // 按钮点击后Stream会释放出数字1 child: const Text("Emit 3"), onPressed: () => _controller.add(3), ), ElevatedButton( // 按钮点击后Stream会释放出数字1 child: const Text("Emit 4"), onPressed: () => _controller.add(4), ), ElevatedButton( // 按钮点击后Stream会释放出数字1 child: const Text("Emit 5"), onPressed: () => _controller.add(5), ), ElevatedButton( // 按钮点击后Stream会释放出数字1 child: const Text("Emit 6"), onPressed: () => _controller.add(6), ), ElevatedButton( // 按钮点击后Stream会释放出一个错误 child: const Text("Emit Error"), onPressed: () => _controller.addError("oops"), ), ElevatedButton( // 按钮点击后Stream会关闭 child: const Text("Close"), onPressed: () => _controller.close(), ), StreamBuilder( stream: _controller.stream .where((event) => event > 3) //过滤大于3 .map((event) => event * 2) //配置流 * 2 .distinct(), // 去除重复的数据 builder: (context, snapshot) { print("正在重新绘制StreamBuilder组件…"); if (snapshot.connectionState == ConnectionState.done) { return const Text("数据流已关闭"); } if (snapshot.hasError) return Text("${snapshot.error}"); if (snapshot.hasData) return Text("${snapshot.data}"); return const Center( child: CircularProgressIndicator(), ); }, ) ], ), ); } }
标签:StreamBuilder,异步,const,Stream,Text,controller,child,return From: https://www.cnblogs.com/xbinbin/p/17971141