flutter Stream流的理解和运用

    技术2022-07-11  81

    1.Stream和Future区别

    Future 表示一个不会立即完成的计算过程。与普通函数直接返回结果不同的是异步函数返回一个将会包含结果的 Future。该 Future 会在结果准备好时通知调用者。

    Stream 是一系列异步事件的序列。其类似于一个异步的 Iterable,不同的是当你向 Iterable 获取下一个事件时它会立即给你,但是 Stream 则不会立即给你而是在它准备好时告诉你。

    2.Stream分类

    流可以分为两类:

    单订阅流(Single Subscription),这种流最多只能有一个监听器(listener)

    多订阅流(Broadcast),这种流可以有多个监听器监听(listener)

    3.Stream四个核心对象

    Stream 事件源StreamController 为了方便控制Stream的流控制器StreamSink 事件输入口StreamSubscription 管理事件订阅

    4.一个简单的实例,来理解这几个对象

    创建对象(先创建StreamController控制,再由控制器创造StreamSink,Stream对象) ///流事件控制器 // ignore: close_sinks StreamController<int> _streamController = StreamController( onListen: (){ print("onListen"); }, onCancel: (){ print("onCancel"); } ); Stream _stream; Stream _eventStream; StreamSink _sink; int _count = 0; @override void dispose() { // TODO: implement dispose super.dispose(); _streamController.close(); _sink.close(); } ///初始化操作 @override void initState() { // TODO: implement initState super.initState(); ///流事件 _stream = _streamController.stream; ///事件入口 _sink = _streamController.sink; } 在需要订阅的组件外层包裹StreamBuild进行事件订阅(builder是将获取的数据进行操作,再展示到组件上的目的) StreamBuilder( stream: _stream, initialData: _count, builder: (context , AsyncSnapshot snapshot){ ///snapshot携带事件入口处闯进来的数据,用snapshot.data获取数据进行处理 if(snapshot.connectionState == ConnectionState.done){ return Text('Done',style: TextStyle(fontSize: 14 , color: Colors.blue),); } int number = snapshot.data; return Text( "$number", style: TextStyle(fontSize: 14 , color: Colors.blue), ); }, ) 事件传入 floatingActionButton: Row( mainAxisAlignment: MainAxisAlignment.center, children: [ FloatingActionButton( child: Icon(Icons.add), tooltip: "Increment", onPressed: ()=>_incrementCounter(), ), SizedBox(width: 20,), // FloatingActionButton( // child: Icon(Icons.close), // tooltip: "Close", // onPressed: ()=>_closeStream, // ), ], ), void _incrementCounter(){ if(_count > 9){ _sink.close(); return; } _count++; ///事件入口对象传入数据 _sink.add(_count); }

    以上就是Stream的基本使用了

    完整代码

    import 'dart:async'; import 'package:flutter/material.dart'; class StreamOnePage extends StatefulWidget { @override _StreamOnePageState createState() => _StreamOnePageState(); } class _StreamOnePageState extends State<StreamOnePage> { ///流事件控制器 // ignore: close_sinks StreamController<int> _streamController = StreamController( onListen: (){ print("onListen"); }, onCancel: (){ print("onCancel"); } ); Stream _stream; Stream _eventStream; StreamSink _sink; int _count = 0; void _incrementCounter(){ if(_count > 9){ _sink.close(); return; } _count++; _sink.add(_count); } void _closeStream(){ _streamController.close(); } @override void dispose() { // TODO: implement dispose super.dispose(); _streamController.close(); _sink.close(); } @override void initState() { // TODO: implement initState super.initState(); ///流事件 _stream = _streamController.stream; ///事件入口 _sink = _streamController.sink; } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: Text("Stream"),), body: Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ Text('You have pushed the button this many times:'), StreamBuilder( stream: _stream, initialData: _count, builder: (context , AsyncSnapshot snapshot){ ///snapshot携带事件入口处闯进来的数据,用snapshot.data获取数据进行处理 if(snapshot.connectionState == ConnectionState.done){ return Text('Done',style: TextStyle(fontSize: 14 , color: Colors.blue),); } int number = snapshot.data; return Text( "$number", style: TextStyle(fontSize: 14 , color: Colors.blue), ); }, ) ], ), ), floatingActionButton: Row( mainAxisAlignment: MainAxisAlignment.center, children: [ FloatingActionButton( child: Icon(Icons.add), tooltip: "Increment", onPressed: ()=>_incrementCounter(), ), SizedBox(width: 20,), // FloatingActionButton( // child: Icon(Icons.close), // tooltip: "Close", // onPressed: ()=>_closeStream, // ), ], ), ); } }

    Stream操作符:

    _streamDuration() async { Duration duration = Duration(seconds: 1); Stream<int> stream3 = Stream.periodic(duration, (data) => data); //stream3 = stream3.take(10);//限制发送次数 stream3 = stream3.takeWhile((element) => element < 10); stream3 = stream3.skip(2); // List<int> listData = await stream3.toList();//一次性返回 // var length = await stream3.length;//数据长度 // stream3 = stream3.map((data) => data + 1);//数据变化 // stream3 = stream3.where((data) => data>3);//数据筛选 // stream3 = stream3.where((data) => data<6); stream3 = stream3.expand((data) => [data, data]); stream3.listen((data) { print("expand==>$data"); }, onError: (error) { print("$error"); }); // print("length==>$length"); // for (int i in listData) { // print("stream3==>$i"); // } // await for(int i in stream3){ // print("stream3==>$i"); // } }

    Stream多订阅流

    import 'dart:async'; import 'package:flutter/material.dart'; class BroadcastStreamPage extends StatefulWidget { @override _BroadcastStreamPageState createState() => _BroadcastStreamPageState(); } class _BroadcastStreamPageState extends State<BroadcastStreamPage> { // ignore: close_sinks StreamController _streamController = StreamController.broadcast(); StreamSubscription _subscription1; StreamSubscription _subscription2; StreamSubscription _subscription3; int _count = 0; int _s1 = 0; int _s2 = 0; int _s3 = 0; _add(){ if(_count > 9){ _subscription1.cancel(); } _count++; _streamController.add(_count); } @override void initState() { // TODO: implement initState super.initState(); _subscription1 = _streamController.stream.listen((event) { setState(() { _s1 +=1; }); }); _subscription2 = _streamController.stream.listen((event) { setState(() { _s2 +=2; }); }); _subscription3 = _streamController.stream.listen((event) { setState(() { _s3 -=1; }); }); } @override void dispose() { // TODO: implement dispose super.dispose(); _streamController.close(); _subscription1.cancel(); _subscription2.cancel(); _subscription3.cancel(); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text("BroadcastStream"), ), body: Column( children: [ Text('Count: $_count'), SizedBox(height: 12.0), Text('S1: $_s1'), SizedBox(height: 12.0), Text('S2: $_s2'), SizedBox(height: 12.0), Text('S3: $_s3'), SizedBox(height: 12.0), FloatingActionButton( onPressed: _add, child: Icon(Icons.plus_one), ), ], ), ); } }

    github地址:https://github.com/korolzhang/flutter_widget

    参考鸣谢:

    https://juejin.im/post/5e9b6aacf265da47bd1bb0d9

    Processed: 0.010, SQL: 9