'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