Flutter嵌套流构建器-在显示数据之前最后一个流为空

时间:2019-05-14 17:30:53

标签: flutter

我正在尝试制作需要嵌套流生成器的应用程序。流构建器看起来像这样。但是小部件是在加载最后一个流之前构建的,所以我在调用getter null时出错,

StreamBuilder(
  stream: some_stream,
  builder: (context, data){
      return StreamBuilder(
         stream: some_stream,
         builder: (context, data){
             return StreamBuilder(
                stream: some_stream,
                builder: (context, data){

                    return someWidget;

              }

            );
          }
        );
       }
    );

2 个答案:

答案 0 :(得分:0)

在Stream没有数据,尚未连接到Stream或值为null的情况下,很有可能会调用StreamBuilder.builder

由您决定确保处理所有这些情况。

要确保初始值永远不会为null,可以设置inialData

Future<String> someFutureString = Future.value('initial data seeded');

new StreamBuilder<String>(
  initialData: await someFutureString,
  builder: (ctx, snapshot) { /* ... */ }
);

这是不好的做法。最好构建一个考虑其快照状态的构建器。构建小部件树应该很快。想象一下,必须等待3秒才能到达initialData。您的小部件树的构建将在第一个await处被阻止。

import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';

wrapInMaterialApp(Widget widget) => MaterialApp(
      home: widget,
    );

main() {
  testWidgets('can await initial data', (WidgetTester tester) async {
    final initialData = Future<String>.value('initial value');
    final stream = Stream.fromIterable(['first']);
    final sb = StreamBuilder<String>(
      initialData: await initialData,
      builder: (ctx, snapshot) {
        return Text('${snapshot.data}');
      },
    );
    await tester.pumpWidget(wrapInMaterialApp(sb));
    // Verify that initial data is present
    expect(find.text('initial value'), findsOneWidget);
  });

  testWidgets('can return subtree if there is data', (WidgetTester tester) async {
    final stream = Stream.fromIterable(['first']);
    final sb = StreamBuilder<String>(
      stream: stream,
      builder: (ctx, snapshot) {
        if (snapshot.hasData) {
          return Text('${snapshot.data}');
        } else
          return Container();
      },
    );
    var wrappedWidget = wrapInMaterialApp(sb);
    await tester.pumpWidget(wrappedWidget);

    expect(find.byType(Container), findsOneWidget);
    expect(find.text('first'), findsNothing);

    await tester.pump();

    expect(find.byType(Container), findsNothing);
    expect(find.text('first'), findsOneWidget);
  });
}

ConnectionState可以通过snapshot.connectionState进行访问,这可以帮助您确定构建器应返回的小部件。

干杯!

答案 1 :(得分:0)

您应该始终采用类似StreamBuilder的结构,

StreamBuilder(
  stream: some_stream,
  builder: (context, data){
      return StreamBuilder(
         stream: some_stream2,
         builder: (context, data){
             if(data.hasError) {
               return Text("Error Occured!!");
             } else if(data.hasData) {
               return StreamBuilder(
                      stream: some_stream,
                      builder: (context, data){
                         if (data.hasError){
                            return Text("Error Occured!!");
                         } else if (data.hasData) {
                            return someWidget;
                         }else {
                            return CircularProgressIndicator();
                         }
                      }
               );
             } else {
               return CircularProgressIndicator();
             }
          }
        );
       }
    );

这将在大多数时间使您免于错误。