Flutter StreamBuilder在初始化时称为两次

时间:2019-08-19 18:49:56

标签: flutter dart stream-builder

StreamBuilder是否总是被调用两次?一次用于初始数据,然后一次用于输入流?

初始化以下StreamBuilder表示,两次调用了build方法。第二个电话比第一个电话晚0.4秒。

流:内部版本1566239814897

流:内部版本1566239815284

import 'dart:async';
import 'dart:ui';

import 'package:flutter/material.dart';
import 'package:nocd/utils/bloc_provider.dart';

void main() =>
    runApp(BlocProvider<MyAppBloc>(bloc: MyAppBloc(), child: MyApp()));

class MyAppBloc extends BlocBase {
  String _page = window.defaultRouteName ?? "";

  /// Stream for [getPage].
  StreamController<String> pageController = StreamController<String>();

  /// Observable navigation route value.
  Stream get getPage => pageController.stream;

  MyAppBloc() {}

  @override
  void dispose() {
    pageController.close();
  }
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    final MyAppBloc myAppBloc = BlocProvider.of<MyAppBloc>(context);
    return StreamBuilder(
      stream: myAppBloc.getPage,
      initialData: "Build",
      builder: (context, snapshot) {
        print("Stream: " +
            snapshot.data +
            DateTime.now().millisecondsSinceEpoch.toString());
        return Container();
      },
    );
  }
}

为什么StreamBuilder被调用两次?

2 个答案:

答案 0 :(得分:0)

StreamBuilder在初始化时进行两次构建调用,一次用于初始数据,第二次用于流数据。

流不保证它们将立即发送数据,因此需要初始数据值。将null传递到initialData会引发InvalidArgument异常。

即使传递的流为null,StreamBuilders也会始终生成两次。

答案 1 :(得分:0)

Streambuilder将被调用2次,第一次是Initial,第二次是Stream。并且仅在状态为 ConnectionState.active”时更改数据。 请参阅官方文档示例。

    StreamBuilder<int>(
  //stream:fire, // a Stream<int> or null
  builder: (BuildContext context, AsyncSnapshot<int> snapshot) {
    if (snapshot.hasError) return Text('Error: ${snapshot.error}');
    switch (snapshot.connectionState) {
      case ConnectionState.none:
        return Text('Select lot');
      case ConnectionState.waiting:
        return Text('Awaiting bids...');
      case ConnectionState.active:
        return Text('\$${snapshot.data}');
      case ConnectionState.done:
        return Text('\$${snapshot.data} (closed)');
    }
    return null; // unreachable
  },
);

StreamBuilder documentation

  

可以通过指定initialData来控制初始快照数据。应该使用此方法来确保第一帧具有期望的值,因为将始终在流侦听器有机会被处理之前调用生成器。

initialData

  

提供此值(大概在创建Stream时以某种方式同步获得)可确保第一帧显示有用的数据。否则,无论流上是否有可用值,都将使用零值构建第一帧:由于流是异步的,因此在初始构建之前无法从流中获取任何事件。