'Flutter TabBar not keeping state when swithing tabs even after using AutomaticKeepAliveClientMixin and super.build(context)
My app has two tabs and switching the tabs doesn't keep its state. I searched the web and found to use AutomaticKeepAliveClientMixin with wantKeepAlive as true and super.build(context). I did exactly what was told by other users across the web and stackoverflow but the problem still exists.
Here is my code:
void main() => runApp(MyApp());
class MyApp extends StatefulWidget {
@override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> with AutomaticKeepAliveClientMixin{
@override
bool get wantKeepAlive => true;
@override
Widget build(BuildContext context) {
super.build(context);
return MaterialApp(
title: 'Flutter GridView',
debugShowCheckedModeBanner: false,
theme: ThemeData(
primaryColor: Colors.blue,
accentColor: Colors.white,
),
home: DefaultTabController(
length: 2,
child: Scaffold(
drawer: Drawer(),
backgroundColor: Colors.blueAccent,
appBar: AppBar(
backgroundColor: Colors.blueAccent,
title: Text('AIO'),
bottom: TabBar(
tabs: <Widget>[
Tab(icon: Icon(Icons.search)),
Tab(icon: Icon(Icons.favorite)),
],
),
),
body: TabBarView(
children: <Widget>[
gridView,
SecondPage(),
],
),
),
),
);
}}
Solution 1:[1]
Use PageStorage, PageStorageBucket and PageStorageKey.
Create an instance field of PageStorageBucket, wrap your TabBarView with PageStorage, then add PageStorageKey to your GridView.
class _MyAppState extends State<MyApp> {
final PageStorageBucket bucket = PageStorageBucket();
//...
body: PageStorage(
bucket: bucket,
child: TabBarView(
children: <Widget>[
gridView, // add to GridView(key: PageStorageKey('MyGridViewKey'), //...
SecondPage(),
],
),
),
//...
Solution 2:[2]
My issue was slightly different than OPs but I want to post it here in case anyone else is running into the same issue. If you're not using a TabBarView (in my case I can't use TabBarView because it doesn't seem to work with dynamically sized pages) and a Center to hold your tab pages like this:
Center(
child: [
Page1(),
Page2(),
][_tabIndex],
)
then the AutomaticKeepAliveClientMixin that I added to Page1State and Page2State was not working for me. I had to use an IndexedStack in order for it to work:
IndexedStack(
index: _tabIndex,
children: [
Page1(),
Page2()
],
)
So it looks like this:
@override
Widget build(BuildContext context) {
return Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Container(
child: TabBar(controller: _tabController, tabs: [
Tab(text: "Tab 1"),
Tab(text: "Tab 2"),
]),
),
IndexedStack(
index: _tabIndex,
children: [
Page1(),
Page2()
],
),
],
);
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | |
| Solution 2 | odiggity |
