flutter Stream流的理解和运用

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

  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值