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主要功能:
  1. 实现局部刷新
  2. 读取流实现读取文件或者下载网络资源等操作
  3. 父子组件之间的数据广播
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(),
              );
            },
          )
        ],
      ),
    );
  }
}

 

 

 

posted on 2024-01-17 22:08  鲤斌  阅读(300)  评论(0)    收藏  举报