Последний поток построителя вложенных потоков Flutter получает значение null перед отображением данных

Я пытаюсь создать приложение, в котором мне нужен построитель вложенных потоков. Конструктор 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;

              }

            );
          }
        );
       }
    );

person Jamilur Rahman    schedule 14.05.2019    source источник
comment
нет, вам нужно объединить три потока в один и использовать один StreamBuilder - см. dart.dev/tutorials/ language / streams и dart.dev/articles/libraries/creating-streams для получения дополнительной информации   -  person pskink    schedule 14.05.2019


Ответы (2)


Вполне возможно, что 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.

Ваше здоровье!

person Daniel V.    schedule 14.05.2019

Вы всегда должны подходить к структуре 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();
             }
          }
        );
       }
    );

Это избавит вас от ошибок в большинстве случаев.

person Jay Mungara    schedule 12.12.2019