flutter - 重建原因“流已被收听”
问题描述
我有 BehaviorSubject,每次我在 TextField 中键入时,它都会从 Firebase 查询中发出一个项目列表,例如全文搜索。我使用 StreamBuilder(在 ListView 内)来监听这个流,并在一个 AnimatedSwitcher 包裹的 Column 中显示所有列表项。
当我尝试滚动视图或刷新列时,我得到“流已被收听”。我尝试了一切,但我无法修复它。
编辑:我添加了一些代码
查看.dart
PostController _postController = new PostController();
ListView(
padding: EdgeInsets.all(12),
children: <Widget>[
//titolo
Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(10)),
color: Color.fromRGBO(242, 242, 242, 1),
),
padding: EdgeInsets.all(8),
child: Column(
children: <Widget>[
StreamBuilder(
stream: _postController.titleStream$,
builder: (BuildContext context, AsyncSnapshot<String> snap) {
return TextField(
onChanged: (String search) => _postController.updateTitle(search),
decoration: InputDecoration(
contentPadding: EdgeInsets.all(12),
border: InputBorder.none,
fillColor: Colors.transparent,
filled: true,
hintText: "titolo",
errorText: snap.error
),
style: TextStyle(color: Colors.black, fontWeight: FontWeight.bold, fontSize: 24),
);
},
),
StreamBuilder(
stream: _postController.superStream,
builder: (BuildContext context, AsyncSnapshot<QuerySnapshot> snap){
return AnimatedSwitcher(
duration: Duration(milliseconds: 500),
transitionBuilder: (child, animation) => SizeTransition(sizeFactor: animation, child: child, axisAlignment: -1,),
child: snap.hasData ? BuildQuestions(snap.data.documents) : Container(width: 0, height: 0)
);
},
),
postController.dart
BehaviorSubject _titleController = new BehaviorSubject<String>();
Observable<String> get titleStream$ =>
_titleController.stream.transform(_validateTitle); //if string is not empty it emits otherwise it emits an error
String get title => _titleController.value;
void updateTitle(String title) => _titleController.add(title);
Observable<QuerySnapshot> get superStream => Observable.combineLatest2(
titleStream$,
Queries.search(_titleController.value), //search stream from firestore api
(String title, QuerySnapshot snap) => snap
);
解决了
我在 StreamBuilder 中有一个提交按钮,它正在侦听另一个 Observable,我用它来检查表单的字段是否不为空。当我输入 TextField 并显示 Column 时,提交按钮滑出视图,当我向下滚动时,StreamBuilder 被重建并尝试再次收听他的流,这会产生错误。解决了:
Observable<bool> get validate => Observable.combineLatest2(titleStream$, descriptionStream$, (t, d) => true).asBroadcastStream();
解决方案
将您的流声明为广播流,如下所示
我使用 rxdart 你应该用你的场景修改它
static var controller =StreamController<Map<String, dynamic>>();
static var _streamObservable = Observable(controller.stream.asBroadcastStream());