【发布时间】:2025-12-04 01:50:02
【问题描述】:
我正在 Flutter 中制作一个电影列表应用程序,当我打开该应用程序时,我正在显示观看次数最多的电影列表。当我单击一个按钮时,我会获取新数据并将其添加到接收器,然后发送到 StreamBuilder 并且应该使用新数据刷新屏幕。
但这不会发生。我无法理解为什么!
这是我的存储库代码:
class MoviesRepository {
final _movieApiProvider = MovieApiProvider();
fetchAllMovies() async => _movieApiProvider.fetchMovieList();
fetchAllSimilarMovies(genreIdeas) async => await _movieApiProvider.fetchMoviesLikeThis(genreIdeas);
fetchTopRatedMovies() async => await _movieApiProvider.fetchTopRatedMovieList();
}
这是我的 bloc 代码:
class MoviesBloc {
final _moviesRepository = MoviesRepository();
final _moviesFetcher = BehaviorSubject<Result>();
Sink<Result> get allMovies => _fetcherController.sink;
final _fetcherController = StreamController<Result>();
Observable<Result> get newResults => _moviesFetcher.stream;
fetchAllMovies() async {
Result model = await _moviesRepository.fetchAllMovies();
allMovies.add(model);
}
fetchTopRatedMovies() async{
Result model = await _moviesRepository.fetchTopRatedMovies();
allMovies.add(model);
}
dispose() {
_moviesFetcher.close();
_fetcherController.close();
}
MoviesBloc() {
_fetcherController.stream.listen(_handle);
}
void _handle(Result event) {
_moviesFetcher.add(event);
}
}
final bloc = MoviesBloc();
更新
这是我的 StreamBuilder 代码:
class HomeScreenListState extends State<HomeScreenList> {
@override
void initState() {
super.initState();
print("init");
bloc.fetchAllMovies();
}
@override
void dispose() {
super.dispose();
bloc.dispose();
}
@override
Widget build(BuildContext context) {
return StreamBuilder<Result>(
builder: (context, snapshot) {
if (snapshot.hasData) {
print("new data is here");
return buildList(snapshot);
} else if (snapshot.hasError) {
return Text('Error!!');
}
return Center(
child: CircularProgressIndicator(),
);
},
stream: bloc.newResults,
);
}
}
这是触发获取新数据并将其添加到接收器的按钮:
child: RaisedButton(onPressed: () {
bloc.fetchTopRatedMovies();
},
此按钮可获取评分最高的电影并添加到同一个接收器。现在 StreamBuilder 应该按照我的想法获取新数据。
问题出在哪里??
【问题讨论】:
-
哪个部分不工作?新结果是否添加到
allMovies接收器?_handle会被调用吗?据我所知,代码看起来应该可以工作。 -
@Edman 很抱歉这么晚才回复,但经过大量调试后,确实调用了 allMovies sink。 _handle 也被调用。不会进行小部件重建。我已经更新了代码的最后一部分,以便在构建小部件时添加日志,但仅在应用启动时调用一次。
-
@Dhruvam Sharma 我正在遵循与你相同的示例,但在我的情况下,streambuilder 快照没有数据(非空)有任何建议吗?
-
@Lekr0 我建议你使用 BehaviourSubject 而不是 Stream Controller。这将使您的任务更轻松。
标签: api flutter movies stream-builder