0

我正在尝试制作一个需要嵌套流构建器的应用程序。Stream 构建器看起来像这样。但是小部件是在加载最后一个流之前构建的,所以我在调用 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;

              }

            );
          }
        );
       }
    );
4

2 回答 2

1

完全有可能StreamBuilder.builder在 Stream 没有数据、尚未连接到 Stream 或值为 null 时调用。

您有责任确保处理所有这些情况。

要确保初始值是 never 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);
  });
}

其他可以帮助您确定您的构建器应该返回什么 Widget 的东西,可以ConnectionState通过snapshot.connectionState.

干杯!

于 2019-05-14T18:47:48.273 回答
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();
             }
          }
        );
       }
    );

这将使您在大多数情况下免于出错。

于 2019-12-12T11:54:48.280 回答