颤振中的流构建器延迟问题

时间:2021-07-16 14:57:52

标签: flutter dart flutter-test

我有一个流构建器,但它显示不同的流查询取决于用户选择。

使用更改选择时有一个问题,即在获取选择的流查询之间有一个小的延迟,所以非常简单,前一个查询显示并立即更改为选定的查询。我想知道有什么方法可以防止在延迟时间内显示查询。

  body: ListView(
    children: <Widget>[
  select(),// decide buyOrSell
  StreamBuilder(
      stream: buyOrSell == "buy"
          ? FirebaseFirestore.instance
              .collection("buy")
              .doc(widget.profileId)
              .collection("barter")
              .orderBy('timestamp', descending: true)
              .snapshots()
          : FirebaseFirestore.instance
              .collection("sell")
              .doc(widget.profileId)
              .collection("barter")
              .orderBy('timestamp', descending: true)
              .snapshots(),

1 个答案:

答案 0 :(得分:1)

参考StreamBuilder官方文档:https://api.flutter.dev/flutter/widgets/StreamBuilder-class.html#widgets.StreamBuilder.1

StreamBuilder builder方法里面有一个AsyncSnapshot值,里面不仅有Stream的数据,还有状态和错误。在构建器方法中,检查 snapshot.hasError 和 snapshot.state。连接有4种状态:

enum ConnectionState {
  /// Not currently connected to any asynchronous computation.
  ///
  /// For example, a [FutureBuilder] whose [FutureBuilder.future] is null.
  none,

  /// Connected to an asynchronous computation and awaiting interaction.
  waiting,

  /// Connected to an active asynchronous computation.
  ///
  /// For example, a [Stream] that has returned at least one value, but is not
  /// yet done.
  active,

  /// Connected to a terminated asynchronous computation.
  done,
}

您的“延迟”是由于这些状态之间的切换造成的,因此理想情况下您需要为每个状态指定返回值。请参阅取自文档的完整示例:

return Scaffold(
  body: ListView(
    children: <Widget>[
      select(), // decide buyOrSell
      StreamBuilder(
        stream: buyOrSell == "buy"
            ? FirebaseFirestore.instance
                .collection("buy")
                .doc(widget.profileId)
                .collection("barter")
                .orderBy('timestamp', descending: true)
                .snapshots()
            : FirebaseFirestore.instance
                .collection("sell")
                .doc(widget.profileId)
                .collection("barter")
                .orderBy('timestamp', descending: true)
                .snapshots(),
        builder: (BuildContext context, AsyncSnapshot<dynamic> snapshot) {
          List<Widget> children;
          if (snapshot.hasError) {
            children = <Widget>[
              const Icon(
                Icons.error_outline,
                color: Colors.red,
                size: 60,
              ),
              Padding(
                padding: const EdgeInsets.only(top: 16),
                child: Text('Error: ${snapshot.error}'),
              ),
              Padding(
                padding: const EdgeInsets.only(top: 8),
                child: Text('Stack trace: ${snapshot.stackTrace}'),
              ),
            ];
          } else {
            switch (snapshot.connectionState) {
              case ConnectionState.none:
                children = const <Widget>[
                  Icon(
                    Icons.info,
                    color: Colors.blue,
                    size: 60,
                  ),
                  Padding(
                    padding: EdgeInsets.only(top: 16),
                    child: Text('Select a lot'),
                  )
                ];
                break;
              case ConnectionState.waiting:
                children = const <Widget>[
                  SizedBox(
                    child: CircularProgressIndicator(),
                    width: 60,
                    height: 60,
                  ),
                  Padding(
                    padding: EdgeInsets.only(top: 16),
                    child: Text('Awaiting bids...'),
                  )
                ];
                break;
              case ConnectionState.active:
                children = <Widget>[
                  const Icon(
                    Icons.check_circle_outline,
                    color: Colors.green,
                    size: 60,
                  ),
                  Padding(
                    padding: const EdgeInsets.only(top: 16),
                    child: Text('\$${snapshot.data}'),
                  )
                ];
                break;
              case ConnectionState.done:
                children = <Widget>[
                  const Icon(
                    Icons.info,
                    color: Colors.blue,
                    size: 60,
                  ),
                  Padding(
                    padding: const EdgeInsets.only(top: 16),
                    child: Text('\$${snapshot.data} (closed)'),
                  )
                ];
                break;
            }
          }

          return Column(
            mainAxisAlignment: MainAxisAlignment.center,
            crossAxisAlignment: CrossAxisAlignment.center,
            children: children,
          );
        },
      ),
    ],
  ),
);