原文

https://medium.com/flutterdev...

注释

异步交互可能须要一个现实的机会来进行总结。偶然,在周期完结之前可能会收回一些值。在 Dart 中,您能够创立一个返回 Stream 的容量,该容量能够在异步过程处于活动状态时发射一些值。假如您须要依据一个 Stream 的快照在 Flutter 中结构一个小部件,那么有一个名为 StreamBuilder 的小部件。

在这个博客中,咱们将摸索 Flutter 中的 StreamBuilder。咱们还将实现一个演示程序,并向您展现如何在您的 Flutter 应用程序中应用 StreamBuilder。

介绍:

StreamBuilder 能够监听公开的流,并返回小部件和捕捉取得的流信息的快照。造溪者提出了两个论点。

A stream

构建器,它能够将流中的多个组件更改为小部件

Stream 像一条线。当您从一端输出值而从另一端输出侦听器时,侦听器将取得该值。一个流能够有多个侦听器,这些侦听器的负载能够取得流水线,流水线将取得等价值。如何在流上搁置值是通过应用流控制器实现的。流构建器是一个小部件,它能够将用户定义的对象更改为流。

建造者:

要应用 StreamBuilder,须要调用上面的构造函数:
const StreamBuilder({Key? key,Stream<T>? stream,T? initialData,required AsyncWidgetBuilder<T> builder,})

实际上,您须要创立一个 Stream 并将其作为流争用传递。而后,在这一点上,您须要传递一个 AsyncWidgetBuilder,该 AsyncWidgetBuilder 可用于结构依赖于 Stream 快照的小部件。

参数:

上面是 StreamBuilderare 的一些参数:
  • Key? key: 小部件的键,用于管制小部件如何被另一个小部件取代
  • Stream<T>? stream: 一个流,其快照能够通过生成器函数取得
  • T? initialData: 将利用这些数据制作初始快照
  • required AsyncWidgetBuilder<T> builder: 生成过程由此生成器应用

如何实现 dart 文件中的代码:

你须要别离在你的代码中实现它:

让咱们创立一个流:

上面的函数返回一个每秒生成一个数字的 Stream。你须要应用 async * 关键字来创立一个流。若要收回值,能够应用 yield 关键字后跟要收回的值。

Stream<int> generateNumbers = (() async* {  await Future<void>.delayed(Duration(seconds: 2));  for (int i = 1; i <= 10; i++) {    await Future<void>.delayed(Duration(seconds: 1));    yield i;  }})();

From that point onward, pass it as the stream argument

从那一点开始,把它作为流参数传递上来

StreamBuilder<int>(stream: generateNumbers,// other arguments)
让咱们创立一个 AsyncWidgetBuilder

构造函数冀望您传递一个类型为 AsyncWidgetBuilder 的命名争用构建器。这是一个有两个参数的函数,它们的类型都是 BuildContext 和 AsyncSnapshot \< t > 。后续的边界(蕴含以后快照)能够用来确定应该出现的内容。

要创立这个函数,首先须要理解 AsyncSnapshot。AsyncSnapshot 是应用异步计算的最新通信的不变形容。在这种独特的状况下,它解决了与 Stream 的最新通信。能够通过 AsyncSnapshot 属性获取流的最新快照。您可能须要应用的属性之一是 connectionState,这个枚举将以后关联状态转换为异步计算,在这种非凡状况下,这种异步计算就是 Steam。

StreamBuilder<int>(  stream: generateNumbers,  builder: (      BuildContext context,      AsyncSnapshot<int> snapshot,      ) {    if (snapshot.connectionState == ConnectionState.waiting) {      return CircularProgressIndicator();    } else if (snapshot.connectionState == ConnectionState.active        || snapshot.connectionState == ConnectionState.done) {      if (snapshot.hasError) {        return const Text('Error');      } else if (snapshot.hasData) {        return Text(            snapshot.data.toString(),            style: const TextStyle(color: Colors._red_, fontSize: 40)        );      } else {        return const Text('Empty data');      }    } else {      return Text('State: ${snapshot.connectionState}');    }  },),

AsyncSnapshot 还有一个名为 hasError 的属性,可用于查看快照是否蕴含非空谬误值。如果异步流动的最新后果失败,hasError 值将无效。为了获取信息,首先,您能够通过获取其 hasData 属性来查看快照是否蕴含信息,如果 Stream 无效地开释了任何非空值,那么 hasData 属性将是无效的。而后,在这一点上,您能够从 AsyncSnapshot 的数据属性获取信息。

因为下面属性的值,您能够计算出应该在屏幕上出现什么。在上面的代码中,当 connectionState 值正在期待时,将显示一个 CircularProgressIndicator。当 connectionState 更改为 active 或 done 时,能够查看快照是否有谬误或信息。建造函数称为 Flutter 管道的检测。因而,它将取得一个与工夫相干的快照子组。这意味着,如果在实际上类似的工夫里,Stream 收回了一些值,那么一部分值可能没有传递给构建器。

枚举有一些可能的值:
  • \> none: 无: 不与任何异步计算关联。如果流为空,则可能产生
  • \> waiting: 期待: 与异步计算关联并期待合作。在这个上下文中,它暗示流还没有实现
  • \> active: 沉闷的: 与流动的异步计算相关联。例如,如果一个 Stream 曾经返回了任何值,但此时还没有完结
  • \> done: > 实现: 与完结的异步计算相关联。在这个上下文中,它暗示流曾经实现
设置初始数据:

您能够抉择传递一个 worth 作为 initialData 参数,这个参数将被利用,直到 Stream 收回 a。如果传递的值不为空,那么当 connectionState 在期待时,hasData 属性在任何事件中首先都将为 true

StreamBuilder<int>(initialData: 0,// other arguments)

要在 connectionState 期待时显示初始数据,应该调整 if snapshot.connectionState = = connectionState.waiting,而后调整下面代码中的块。

if (snapshot.connectionState == ConnectionState.waiting) {  return Column(    crossAxisAlignment: CrossAxisAlignment.center,    mainAxisAlignment: MainAxisAlignment.center,    children: [      CircularProgressIndicator(),      Visibility(        visible: snapshot.hasData,        child: Text(          snapshot.data.toString(),          style: const TextStyle(color: Colors._black_, fontSize: 24),        ),      ),    ],  );}

当咱们运行应用程序,咱们应该失去屏幕的输入像上面的屏幕视频。

Code File:

明码档案:

import 'package:flutter/material.dart';import 'package:flutter_steambuilder_demo/splash_screen.dart';void main() => runApp(MyApp());class MyApp extends StatelessWidget {  @override  Widget build(BuildContext context) {    return MaterialApp(      home: Splash(),      debugShowCheckedModeBanner: false,    );  }}Stream<int> generateNumbers = (() async* {  await Future<void>.delayed(Duration(seconds: 2));  for (int i = 1; i <= 10; i++) {    await Future<void>.delayed(Duration(seconds: 1));    yield i;  }})();class StreamBuilderDemo extends StatefulWidget {  @override  State<StatefulWidget> createState() {    return _StreamBuilderDemoState ();  }}class _StreamBuilderDemoState extends State<StreamBuilderDemo> {  @override  initState() {    super.initState();  }  @override  Widget build(BuildContext context) {    return Scaffold(      appBar: AppBar(        automaticallyImplyLeading: false,        title: const Text('Flutter StreamBuilder Demo'),      ),      body: SizedBox(        width: double._infinity_,        child: Center(          child: StreamBuilder<int>(            stream: generateNumbers,            initialData: 0,            builder: (                BuildContext context,                AsyncSnapshot<int> snapshot,                ) {              if (snapshot.connectionState == ConnectionState.waiting) {                return Column(                  crossAxisAlignment: CrossAxisAlignment.center,                  mainAxisAlignment: MainAxisAlignment.center,                  children: [                    CircularProgressIndicator(),                    Visibility(                      visible: snapshot.hasData,                      child: Text(                        snapshot.data.toString(),                        style: const TextStyle(color: Colors._black_, fontSize: 24),                      ),                    ),                  ],                );              } else if (snapshot.connectionState == ConnectionState.active                  || snapshot.connectionState == ConnectionState.done) {                if (snapshot.hasError) {                  return const Text('Error');                } else if (snapshot.hasData) {                  return Text(                      snapshot.data.toString(),                      style: const TextStyle(color: Colors._red_, fontSize: 40)                  );                } else {                  return const Text('Empty data');                }              } else {                return Text('State: ${snapshot.connectionState}');              }            },          ),        ),      ),    );  }}

结语:

在本文中,我曾经简略介绍了 StreamBuilder 的根本构造; 您能够依据本人的抉择批改这段代码。这是我对 StreamBuilder On User Interaction 的一个小小介绍,它正在应用 Flutter 工作。


© 猫哥

  • https://ducafecat.tech/
  • https://github.com/ducafecat
  • 微信群 ducafecat
  • b 站 https://space.bilibili.com/40...

往期

开源

GetX Quick Start

https://github.com/ducafecat/...

新闻客户端

https://github.com/ducafecat/...

strapi 手册译文

https://getstrapi.cn

微信探讨群 ducafecat

系列汇合

译文

https://ducafecat.tech/catego...

开源我的项目

https://ducafecat.tech/catego...

Dart 编程语言根底

https://space.bilibili.com/40...

Flutter 零根底入门

https://space.bilibili.com/40...

Flutter 实战从零开始 新闻客户端

https://space.bilibili.com/40...

Flutter 组件开发

https://space.bilibili.com/40...

Flutter Bloc

https://space.bilibili.com/40...

Flutter Getx4

https://space.bilibili.com/40...

Docker Yapi

https://space.bilibili.com/40...