我如何使用 Provider 为 PageView() 提供一个 bloc 而无需 child 每次切换页面时重新订阅?

How can I use Provider to provide a bloc to a PageView() without the child resubscribing everytime I switch page?

我正在使用 Provider 通过静态创建方法将我的集团提供给名为 TheGroupPage 的小部件

  static Widget create(BuildContext context, GroupModel group) {
    final database = Provider.of<DatabaseService>(context);
    return Provider(
      create: (_) => GroupMembersBloc(database, group),
      child: TheGroupPage(group),
      dispose: (BuildContext context, GroupMembersBloc bloc) => bloc.dispose(),
    );
  }

该小部件有一个包含 3 个页面的 PageView()

  PageView(children: [
    TheGroupNotificationsView(),
    TheGroupMembersView(group),
    TheGroupSettingsView(group),
  ])

组成员视图查找 GroupMembersBloc

GroupMembersBloc bloc = Provider.of<GroupMembersBloc>(context);

我也试过 listen to false 但这没有用。我希望小部件监听任何更改。该页面使用该集团的流来绘制组成员列表

class GroupMembersBloc{

  StreamController<List<UserModel>> _controller = StreamController<List<UserModel>>();
  Stream<List<UserModel>> get stream => _controller.stream;

  GroupMembersBloc(DatabaseService database, GroupModel group)
  {
   _controller.addStream(database.groupMembersStream(group));
  }

  void dispose(){
    _controller.close();
  }
}

问题是当我在 PageView() 中切换页面时,第一次显示页面后出现错误。错误显示 Bad state: Stream has already been listened to. 我该如何解决这个问题?

那是因为流控制器只允许 1 个订阅(或 1 个侦听器),您可以使用 [StreamController<List<UserModel>>.broadcast()][1] 构造函数而不是 StreamController>()。

我最终将 StreamBuilder 移动到 PageView() 上方的父小部件,这解决了问题。