【问题标题】:Rebuild cause "Stream has already been listened to"重建原因“流已被收听”
【发布时间】:2020-01-13 08:11:42
【问题描述】:

我有一个 BehaviorSubject,每次我在 TextField 中键入时,它都会从 Firebase 查询中发出一个项目列表,例如全文搜索。 我使用 StreamBuilder(在 ListView 中)来监听这个流,并在一个用 AnimatedSwitcher 包裹的 Column 中显示所有列表项。

当我尝试滚动视图或刷新列时,我得到“流已被收听”。我尝试了所有方法,但无法修复它。

编辑:我添加了一些代码

view.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();

【问题讨论】:

  • 能否分享一些代码,以便我们为您提供帮助。
  • @Muldec 添加了一些代码

标签: flutter dart rxdart


【解决方案1】:

将您的流声明为广播流,如下所示

我使用 rxdart 你应该根据你的场景修改它

  static var controller =StreamController<Map<String, dynamic>>();
  static var _streamObservable = Observable(controller.stream.asBroadcastStream());

【讨论】:

  • 我已经将 rxdart 与 BehaviorSubject 一起使用,正如我在问题中提到的,默认情况下它是一个广播流。反正我试过了,还是一样的错误
猜你喜欢
  • 2019-05-19
  • 1970-01-01
  • 2019-03-23
  • 1970-01-01
  • 2021-12-26
  • 2018-12-26
  • 2021-06-19
  • 2021-02-26
  • 2023-03-29
相关资源
最近更新 更多