RefreshIndicator 不会旋转,直到从 api 中使用 flutter 中的 bloc 获取数据

par*_*ras 2 dart flutter bloc

我想实现当用户拉动刷新时的行为,指示器不断旋转,直到以块模式从网络获取数据。事实上,我知道发生这种情况的原因,因为刷新方法立即返回。如何阻止此方法直到从网络获取数据。我如何等待数据来自网络。谢谢!

Future<void> _refresh() async{
    context.read<PostBloc>(RefreshEvent());
}

@override
Widget build(BuildContext context) {
  return BlocBuilder<PostBloc, PostStates>(builder: (context, state){
    switch (state.status){
      case PostStatus.failure:
        return const Center(child: Text('failed to fetch posts'));
      case PostStatus.success:
        if (state.posts.isEmpty) {
          return const Center(child: Text('no posts'));
        }
        return RefreshIndicator(
          triggerMode: RefreshIndicatorTriggerMode.onEdge,
          onRefresh: () async {
            await _refresh();
          },
          child: ListView.builder(
            physics:  AlwaysScrollableScrollPhysics(),
            itemBuilder: (context, index){
              if (index >= state.posts.length){
                return BottomLoader();
              }
              return PostListItem(post: state.posts[index]);
            },
            itemCount: state.hasReachedMax ? state.posts.length : state.posts.length + 1,
            controller: _scrollController,
          ),
        );
      case PostStatus.initial:
        return const Center(child: CircularProgressIndicator());
  
    }
  });
}
Run Code Online (Sandbox Code Playgroud)

Tri*_*ine 10

改变这个:

Future<void> _refresh() async{
  context.read<PostBloc>(RefreshEvent());
}
Run Code Online (Sandbox Code Playgroud)

对此:

Future<void> _refresh() async{
  Future block = context.read<TestBloc>().stream.first;
  context.read<TestBloc>().add(TestEvent());
  await block;
}
Run Code Online (Sandbox Code Playgroud)

编辑说明:

块只是将事件转换为状态的流。BlocBuilder例如,A只是 a 的修改版本StreamBuilder。这就是为什么我们可以直接收听这个流。

该行context.read<TestBloc>().stream.first订阅流,获取第一个发出的状态并关闭订阅。目前我们还没有新的状态。这就是为什么现在要拥有未来。

调用此context.read<TestBloc>().add(TestEvent())函数后,实际上会使您的块发出一个新状态。

然后我们要等待未来完成。换句话说,我们要等待我们读取的状态stream.first。为此,我们必须等待未来。

你可能会问为什么我们在将事件添加到块后不监听更改,如下所示:

Future<void> _refresh() async{
  context.read<TestBloc>().add(TestEvent());
  await context.read<TestBloc>().stream.first;
}
Run Code Online (Sandbox Code Playgroud)

问题是,在极少数情况下,我们可能会stream.first错过我们的状态PostStates并正在等待下一个新状态。这将导致 RefreshIndicator 无限旋转。因此,我们必须拆分该命令,以确保我们在添加新事件之前实际监听新状态。