我正在尝试制作需要嵌套流生成器的应用程序。流构建器看起来像这样。但是小部件是在加载最后一个流之前构建的,所以我在调用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;
}
);
}
);
}
);
答案 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();
}
}
);
}
);
这将在大多数时间使您免于错误。