Dart 错误状态:在flutter中从addStream添加项目时,无法关闭主题

Dart 错误状态:在flutter中从addStream添加项目时,无法关闭主题,dart,flutter,rxdart,Dart,Flutter,Rxdart,我使用RxDart来观察更改并相应地更新UI。当应用程序启动时,我正在进行网络呼叫并成功获取数据,观察更改并相应更新UI。但是当我在关闭屏幕时处理主题时。它给出了以下错误: ══╡ EXCEPTION CAUGHT BY WIDGETS LIBRARY ╞═══════════════════════════════════════════════════════════ I/flutter (15524): The following StateError was thrown while f

我使用RxDart来观察更改并相应地更新UI。当应用程序启动时,我正在进行网络呼叫并成功获取数据,观察更改并相应更新UI。但是当我在关闭屏幕时处理
主题时。它给出了以下错误:

══╡ EXCEPTION CAUGHT BY WIDGETS LIBRARY ╞═══════════════════════════════════════════════════════════
I/flutter (15524): The following StateError was thrown while finalizing the widget tree:
I/flutter (15524): Bad state: You cannot close the subject while items are being added from addStream
下面是bloc类:

class MovieDetailBloc {
  final _repository = Repository();
  final _movieId = PublishSubject<int>();
  final _trailers = BehaviorSubject<Future<TrailerModel>>();

  Function(int) get fetchTrailersById => _movieId.sink.add;
  Observable<Future<TrailerModel>> get movieTrailers => _trailers.stream;

  MovieDetailBloc() {
    _movieId.stream.transform(_itemTransformer()).pipe(_trailers);
  }

  dispose() {
    _movieId.close();
    _trailers.close();
  }

  _itemTransformer() {
    return ScanStreamTransformer(
      (Future<TrailerModel> trailer, int id, int index) {
        print(index);
        trailer = _repository.fetchTrailers(id);
        return trailer;
      },
    );
  }
}
classmoviedetailbloc{
最终_repository=repository();
最终_movieId=PublishSubject();
最终_=行为主体();
函数(int)get fetchtrailersbyd=>\u movieId.sink.add;
可观察的get movieTrailers=>\u trailes.stream;
MovieDetailBloc(){
_movieId.stream.transform(_itemTransformer()).pipe(_trailes);
}
处置{
_movieId.close();
_拖车。关闭();
}
_itemTransformer(){
回程扫描变压器(
(未来预告片,整数id,整数索引){
打印(索引);
拖车=_repository.fetchtrailes(id);
返回拖车;
},
);
}
}
这是UI屏幕,我将其称为:

import 'dart:async';

import 'package:flutter/material.dart';
import '../blocs/movie_detail_bloc_provider.dart';
import '../models/trailer_model.dart';

class MovieDetail extends StatefulWidget {
  final posterUrl;
  final description;
  final releaseDate;
  final String title;
  final String voteAverage;
  final int movieId;

  MovieDetail({
    this.title,
    this.posterUrl,
    this.description,
    this.releaseDate,
    this.voteAverage,
    this.movieId,
  });

  @override
  State<StatefulWidget> createState() {
    return MovieDetailState(
      title: title,
      posterUrl: posterUrl,
      description: description,
      releaseDate: releaseDate,
      voteAverage: voteAverage,
      movieId: movieId,
    );
  }
}

class MovieDetailState extends State<MovieDetail> {
  final posterUrl;
  final description;
  final releaseDate;
  final String title;
  final String voteAverage;
  final int movieId;

  MovieDetailBloc bloc;

  MovieDetailState({
    this.title,
    this.posterUrl,
    this.description,
    this.releaseDate,
    this.voteAverage,
    this.movieId,
  });

  @override
  void didChangeDependencies() {
    bloc = MovieDetailBlocProvider.of(context);
    bloc.fetchTrailersById(movieId);
    super.didChangeDependencies();

  }

  @override
  void dispose() {
    bloc.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: NestedScrollView(
        headerSliverBuilder: (BuildContext context, bool innerBoxIsScrolled) {
          return <Widget>[
            SliverAppBar(
              expandedHeight: 220.0,
              floating: false,
              pinned: false,
              flexibleSpace: FlexibleSpaceBar(
                  background: Image.network(
                "https://image.tmdb.org/t/p/w500$posterUrl",
                fit: BoxFit.cover,
              )),
            ),
          ];
        },
        body: Padding(
          padding: const EdgeInsets.all(10.0),
          child: Column(
            crossAxisAlignment: CrossAxisAlignment.start,
            children: <Widget>[
              Container(margin: EdgeInsets.only(top: 5.0)),
              Text(
                title,
                style: TextStyle(
                  fontSize: 25.0,
                  fontWeight: FontWeight.bold,
                ),
              ),
              Container(margin: EdgeInsets.only(top: 8.0, bottom: 8.0)),
              Row(
                children: <Widget>[
                  Icon(
                    Icons.favorite,
                    color: Colors.red,
                  ),
                  Container(
                    margin: EdgeInsets.only(left: 1.0, right: 1.0),
                  ),
                  Text(
                    voteAverage,
                    style: TextStyle(
                      fontSize: 18.0,
                    ),
                  ),
                  Container(
                    margin: EdgeInsets.only(left: 10.0, right: 10.0),
                  ),
                  Text(
                    releaseDate,
                    style: TextStyle(
                      fontSize: 18.0,
                    ),
                  ),
                ],
              ),
              Container(margin: EdgeInsets.only(top: 8.0, bottom: 8.0)),
              Text(description),
              Container(margin: EdgeInsets.only(top: 8.0, bottom: 8.0)),
              Text(
                "Trailer",
                style: TextStyle(
                  fontSize: 25.0,
                  fontWeight: FontWeight.bold,
                ),
              ),
              Container(margin: EdgeInsets.only(top: 8.0, bottom: 8.0)),
              StreamBuilder(
                stream: bloc.movieTrailers,
                builder:
                    (context, AsyncSnapshot<Future<TrailerModel>> snapshot) {
                  if (snapshot.hasData) {
                    return FutureBuilder(
                      future: snapshot.data,
                      builder:
                          (context, AsyncSnapshot<TrailerModel> itemSnapShot) {
                        if (itemSnapShot.hasData) {
                          if (itemSnapShot.data.results.length > 0)
                            return trailerLayout(itemSnapShot.data);
                          else
                            return noTrailer(itemSnapShot.data);
                        } else {
                          return CircularProgressIndicator();
                        }
                      },
                    );
                  } else {
                    return CircularProgressIndicator();
                  }
                },
              ),
            ],
          ),
        ),
      ),
    );
  }

  Widget noTrailer(TrailerModel data) {
    return Center(
      child: Container(
        child: Text("No trailer available"),
      ),
    );
  }
}

Widget trailerLayout(TrailerModel data) {
  return Row(
    children: <Widget>[
      Expanded(
        child: Column(
          children: <Widget>[
            Container(
              margin: EdgeInsets.all(5.0),
              height: 100.0,
              color: Colors.grey,
            ),
            Text(
              data.results[0].name,
              maxLines: 1,
              overflow: TextOverflow.ellipsis,
            ),
          ],
        ),
      ),
      Expanded(
        child: Column(
          children: <Widget>[
            Container(
              margin: EdgeInsets.all(5.0),
              height: 100.0,
              color: Colors.grey,
            ),
            Text(
              data.results[1].name,
              maxLines: 1,
              overflow: TextOverflow.ellipsis,
            ),
          ],
        ),
      ),
    ],
  );
}
导入'dart:async';
进口“包装:颤振/材料.省道”;
导入“../blocs/movie_detail_bloc_provider.dart”;
导入“../models/trailer_model.dart”;
类MovieDetail扩展StatefulWidget{
最后一个月;
最后说明;
最终发布日期;
最后的字符串标题;
最终字符串voteAverage;
最终国际电影ID;
电影细节({
这个名字,
这是posterUrl,
这个.说明,,
这个,发布日期,
这是平均值,
这个,电影ID,
});
@凌驾
状态createState(){
返回电影详细信息状态(
标题:标题,,
posterUrl:posterUrl,
描述:描述,
releaseDate:releaseDate,
voteAverage:voteAverage,
电影ID:movieId,
);
}
}
类MovieDetailState扩展了状态{
最后一个月;
最后说明;
最终发布日期;
最后的字符串标题;
最终字符串voteAverage;
最终国际电影ID;
电影集团;
电影状态({
这个名字,
这是posterUrl,
这个.说明,,
这个,发布日期,
这是平均值,
这个,电影ID,
});
@凌驾
void didChangeDependencies(){
bloc=MovieDetailBlocProvider.of(上下文);
集团。fetchTrailersById(电影ID);
super.didChangeDependencies();
}
@凌驾
无效处置(){
集团处置();
super.dispose();
}
@凌驾
小部件构建(构建上下文){
返回脚手架(
正文:嵌套滚动视图(
headerSliverBuilder:(BuildContext上下文,boolInnerBoxIsCrolled){
返回[
滑杆(
扩展高度:220.0,
浮动:假,
错,,
flexibleSpace:FlexibleSpaceBar(
背景:Image.net(
"https://image.tmdb.org/t/p/w500$posterUrl“,
适合:BoxFit.cover,
)),
),
];
},
主体:填充物(
填充:常数边集全部(10.0),
子:列(
crossAxisAlignment:crossAxisAlignment.start,
儿童:[
容器(边距:仅限边集(顶部:5.0)),
正文(
标题
样式:TextStyle(
字体大小:25.0,
fontWeight:fontWeight.bold,
),
),
容器(仅限边缘集(顶部:8.0,底部:8.0)),
划船(
儿童:[
图标(
我的最爱,
颜色:颜色,红色,
),
容器(
边距:仅限边集(左:1.0,右:1.0),
),
正文(
voteAverage,
样式:TextStyle(
字体大小:18.0,
),
),
容器(
边距:仅限边集(左:10.0,右:10.0),
),
正文(
发布日期,
样式:TextStyle(
字体大小:18.0,
),
),
],
),
容器(仅限边缘集(顶部:8.0,底部:8.0)),
文本(说明),
容器(仅限边缘集(顶部:8.0,底部:8.0)),
正文(
“预告片”,
样式:TextStyle(
字体大小:25.0,
fontWeight:fontWeight.bold,
),
),
容器(仅限边缘集(顶部:8.0,底部:8.0)),
StreamBuilder(
流:集团,电影人,
建设者:
(上下文,异步快照){
if(snapshot.hasData){
回归未来建设者(
未来:snapshot.data,
建设者:
(上下文,异步快照项快照){
if(itemSnapShot.hasData){
如果(itemSnapShot.data.results.length>0)
返回trailerLayout(itemsnashot.data);
其他的
返回noTrailer(itemSnapShot.data);
}否则{
返回循环ProgressIndicator();
}
},
);
}否则{
返回循环ProgressIndicator();
}
},
),
],
),
),
),
);
}
小部件noTrailer(TrailerModel数据){
返回中心(
子:容器(
子项:文本(“无可用预告片”),
),
);
}
}
小部件trailerLayout(TrailerModel数据){
返回行(
奇尔德雷
  dispose() async {
    _movieId.close();
    await _trailers.drain();
    _trailers.close();
  }
MovieDetailBloc() {
  _movieId.stream.transform(_itemTransformer()).pipe(_trailers);
}
MovieDetailBloc() {
  _movieId.stream.transform(_itemTransformer()).listen((data) {
    if (!_categories.isClosed) {
      _trailers.add(data);
    }
  });
}