【发布时间】:2021-03-16 15:37:18
【问题描述】:
我正在尝试在 Flutter 应用程序中使用 bloc 架构,为此我使用了 StreamController 和 StreamBuilder。问题是,StreamBuilder 每次返回时都会重复最后一个 snapshot.data。我正在嵌套 StreamBuilders。所以有一个主要的 StreamBuilder。它的流在 mainBloc 文件中定义。 InitialData 为 SomeEvent 并返回 someView。
SomeView 是另一个带有相应块和流的 StreamBuilder。初始数据是初始事件。在按下按钮时,SecondEvent 被添加到块接收器,因此小部件发生变化。在新视图中有另一个按钮,点击它时 mainBloc 应该再次显示相同的 SomeView。
问题就在这里。 SomeView StreamBuilder 接收到的snapshot.data 与上一个相同,但最后一个没有再次添加到sink。所以我不明白 - 这是 StreamBuilder 应该如何工作的吗?我想要实现的是 snapshot.data 有 InitialEvent 。这可能吗?或者至少不要在不触发的情况下重复 snapshot.data。
下面的代码演示了整个问题。
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
MainBloc mainBloc;
Bloc bloc;
MyApp() {
mainBloc = MainBloc();
bloc = Bloc();
}
Widget mainView() {
return StreamBuilder<MainEvent>(
stream: mainBloc.mainStream,
initialData: SomeEvent(),
builder: (
context,
snapshot,
) {
if (snapshot.hasData) {
MainEvent event = snapshot.data;
if (event is SomeEvent) {
return someView();
}
if (event is SomeEventTwo) {
return someView();
}
} else {
return Container(height: 0, width: 0);
}
},
);
}
Widget someView() {
return StreamBuilder<Event>(
stream: bloc.stream,
initialData: InitialEvent(),
builder: (
context,
snapshot,
) {
if (snapshot.hasData) {
Event event = snapshot.data;
if (event is InitialEvent) {
return Column(
children: [
Center(
child: Text("Initial event"),
),
FlatButton(
onPressed: () {
bloc.secondEvent();
},
child: Text("Trigger Second event"),
color: Colors.pink,
),
],
);
}
if (event is SecondEvent) {
return Center(
child: FlatButton(
child: Text("Show same screen again"),
onPressed: () {
bloc.dispose();
bloc = Bloc();
mainBloc.showScreenTwo();
},
color: Colors.blue,
),
);
}
} else {
return Container(height: 0, width: 0);
}
},
);
}
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
backgroundColor: Colors.grey,
),
body: mainView(),
),
);
}
}
这些是集团: 主块:
class MainBloc {
StreamController<MainEvent> _mainStreamController;
StreamSink<MainEvent> get _mainSink => _mainStreamController.sink;
Stream<MainEvent> get mainStream => _mainStreamController.stream;
MainBloc() {
_mainStreamController = StreamController<MainEvent>();
}
void showScreen() {
_mainSink.add(SomeEvent());
}
void showScreenTwo() {
_mainSink.add(SomeEventTwo());
}
}
abstract class MainEvent {}
class SomeEvent extends MainEvent {}
class SomeEventTwo extends MainEvent {}
集团:
class Bloc {
StreamController<Event> _controller;
StreamSink<Event> get _sink => _controller.sink;
Stream<Event> get stream => _controller.stream;
Bloc() {
_controller = StreamController<Event>();
}
void secondEvent() async {
_sink.add(SecondEvent());
}
dispose() {
_controller.close();
}
}
abstract class Event {}
class InitialEvent extends Event {}
class SecondEvent extends Event {}
【问题讨论】:
标签: flutter bloc stream-builder