为啥 StreamBuilder 中没有刷新数据?

Posted

技术标签:

【中文标题】为啥 StreamBuilder 中没有刷新数据?【英文标题】:Why is data not being refreshed in StreamBuilder?为什么 StreamBuilder 中没有刷新数据? 【发布时间】:2019-06-24 01:37:22 【问题描述】:

我正在 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。这将使您的任务更轻松。 【参考方案1】:

您可以在 BLoC 实现旁边使用 Equatable 来管理屏幕上的状态更改。这是我建议尝试的guide。

【讨论】:

以上是关于为啥 StreamBuilder 中没有刷新数据?的主要内容,如果未能解决你的问题,请参考以下文章

如何更新 Storage 中的图片并刷新 Streambuilder 以显示新图片?

Flutter 实现局部刷新 StreamBuilder 实例详解

Flutter 实现局部刷新 StreamBuilder 实例详解

为啥 NotifyParser 的任何更改都不会使用 Provider / ChangeNotifier / Streambuilder 在 UI 中呈现,而是来自服务类

为啥使用 InheritedWidget 而我们可以使用 Broadcast Streams | StreamBuilder 和静态变量

我可以使用 streamBuilder 从 Api 获取实时数据吗