flutter_bloc subwidget 关闭父 widget 的 bloc

flutter_bloc subwidget closes the bloc of the parent widget

我正在使用 flutter_bloc 包。

我有一个带有标签栏的页面。 该页面创建一个 bloc 并将其提供给用作选项卡内容的小部件。

class _MyScreenState extends State<MyScreen> {
  MyBloc _myBloc;
  ...

  Widget _buildTabBar() {
  ...

    var children = [
    _buildFirstTab()
    _buildSecondTab(),
    ];

    return WillPopScope(
      onWillPop: _onWillPop,
      child: DefaultTabController(
      length: children.length,
      child: Scaffold(
        appBar: PreferredSize(
            preferredSize: Size.fromHeight(75.0),
            child: AppBar(
              bottom: TabBar(isScrollable: true, tabs: tabs),
            )),
        body: TabBarView(
          children: children,
        ),
      ),
    ),
  );
  }
..
}

Widget _buildSecondTab() {
  if (_myBloc == null) {
    _myBloc = MyBloc(<..initialdata..>);
  }
  _myBloc.add(LoadServerDataEvent());

  return BlocProvider<MyBloc>(create: (_) => _myBloc, child: SecondTab());
}

第二个选项卡上的小部件从 BlocProvider 获取 bloc 并使用它。

class _SecondTabState extends State<SecondTab> {
  MyBloc _myBloc;

  @override
  void initState() {
    _myBloc = BlocProvider.of<MyBloc>(context);
    super.initState();
  }

我的问题是,当我在选项卡之间切换时,该块会自动关闭。

这有点奇怪,因为该块仍在页面上使用。

嗯,你做错了几件事:

  1. 如果您希望您的 bloc 在第一个和第二个选项卡中都可以访问,您应该用它包裹整个选项卡栏,
  2. 你在 _MyScreenState 中保留一个 bloc 的实例并使用 lazy init singeltone if (_myBloc == null) _myBloc = MyBloc(),
  3. 做一些魔术,这很奇怪
  4. 大多数情况下_myBloc.add(LoadServerDataEvent());应该在_SecondTabStateinitState方法中触发。
  5. bloc 从 UI 获取初始数据是非常不寻常的。如果你想使用 blocs 构建你的架构,这个初始数据应该来自另一个 bloc.

但是,如果您想向第二个选项卡提供现有的 bloc 并防止它被关闭,您应该使用:

BlocProvider.value(
  value: _myBloc,
  child: SecondTab(),
);

改为:

BlocProvider<MyBloc>(create: (_) => _myBloc, child: SecondTab());