Issue
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.
Solution
Well, you are doing a couple of things wrong:
- if you want your
bloc
to be accessible in both first and second tab you should wrap the whole tab bar with it, - that’s very odd that you keep an instance of a bloc in
_MyScreenState
and do some magic with lazy init singeltoneif (_myBloc == null) _myBloc = MyBloc()
, - The
_myBloc.add(LoadServerDataEvent());
in most cases should be triggered ininitState
method of the_SecondTabState
. - That’s very unusal that a
bloc
gets initial data from the UI. If you want to build your architecture usingblocs
this initial data should come from anotherbloc
.
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());
Answered By – Karol Lisiewicz
Answer Checked By – Willingham (FlutterFixes Volunteer)