-1

I am using the flutter_bloc package.

I have a page with a tabbar. The page creates a bloc and provides it to the widgets, which are used as tab content.

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());
}

The widget on the second tab gets the bloc from the BlocProvider and uses it.

class _SecondTabState extends State<SecondTab> {
  MyBloc _myBloc;

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

My problem is that the block is automatically closed when I switch between the tabs.

This is kind of strange, because the block is still used on the page.

A.K.
  • 568
  • 5
  • 17

1 Answers1

1

Well, you are doing a couple of things wrong:

  1. if you want your bloc to be accessible in both first and second tab you should wrap the whole tab bar with it,
  2. that's very odd that you keep an instance of a bloc in _MyScreenState and do some magic with lazy init singeltone if (_myBloc == null) _myBloc = MyBloc(),
  3. The _myBloc.add(LoadServerDataEvent()); in most cases should be triggered in initState method of the _SecondTabState .
  4. That's very unusal that a bloc gets initial data from the UI. If you want to build your architecture using blocs this initial data should come from another bloc.

But if you want to provide an existing bloc to the second tab and prevent it from being closed you should use:

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

Instead:

BlocProvider<MyBloc>(create: (_) => _myBloc, child: SecondTab());
Karol Lisiewicz
  • 654
  • 5
  • 15
  • 1
    Hi, thanks for your reply. 1. 2. Thats some old code. In the first implementation i had got 2 blocs, and the second needs some data from the first. It´s a stupid implementation. I corrected it. 3. Ok thanks. 4. I did not have blocs in the whole application. In this case the screen gets an ID that is not from a block. This bloc needs the ID to load the data. – A.K. Feb 07 '20 at 07:37