Prevent Cupertino tabs to hold the state when switching tabs

781 Views Asked by At

The default implementation of Material's Scaffold & BottomNavigationBar is to destroy and re-create each tab in each tab change.

In the case of CupertinoTabScaffold, CupertinoTabView and CupertinoPageScaffold the behavior is different: the state of each tab is maintained, so switching between tabs won't re-trigger the initState() method of the tab in each change.

My question is: how to modify this behaviour to act the same as Material? I want each tab to be destroyed and re-created, thus calling the initState() method in each tab change, same as with the Material Widgets.

Thanks.

1

There are 1 best solutions below

7
On

I would say this is a hack, but one way to actually have elements rebuild is to just use new elements.

But obviously, you need the same widget class to be rendered, so how can it be new ?

Keys.

Flutter check the type of your widget as well as it's key (if provided) to validate whether an widget is same or not so as to rebuild.

You can use keys this way. Consider this simple example.

@override
Widget build(BuildContext context) {
  return CupertinoTabScaffold(
    tabBar: CupertinoTabBar(
      items: [
        BottomNavigationBarItem(icon: Icon(Icons.add_a_photo)),
        BottomNavigationBarItem(icon: Icon(Icons.add)),
        BottomNavigationBarItem(icon: Icon(Icons.calendar)),
      ],
    ),
    tabBuilder: (_, i) => Sample(
      key: ValueKey(Random().nextInt(255)),
    ),
  );
}

I have a Sample class which I am using to build each screen in the CupertinoTabScaffold. But instead of using it like Sample(), I have passed an extra key parameter which is just a random number.

Now, my Sample class looks like this,

class Sample extends StatefulWidget {
  Sample({Key key}) : super(key: key);

  @override
  State<StatefulWidget> createState() {
    return SampleState();
  }
}

Now, even if you change something in your SampleState class and then visit another Tab and then comeback to the previous Tab, since you are using a new Key, Flutter will think it is a new Widget and will rebuild it.

Problem solved.

However, I must ask, why though ?