Day 28: How to Preserve Tab State When Switching Tabs in Flutter with Our Noted App
Hey Flutter friends! đ If youâre working on a Flutter app with a TabBar
, youâve probably noticed this frustrating quirkâwhenever you switch between tabs, the state of each tab resets. For example, maybe you have a form, a counter, or some complex UI in one tab, and when you switch back to it after navigating away, all your progress is lost. đ
This issue can ruin the user experience, especially in apps where maintaining data across different screens is crucial. The good news? Thereâs a way to preserve the state of your tabs as users switch between them, and itâs easier than you might think! In this post, weâll dive deep into how to keep your TabBar
state intact while switching tabs in Flutter.
Letâs get started!
| Why Does Tab State Reset in Flutter?
Before we jump into the solution, letâs quickly understand the problem.
By default, Flutter rebuilds a screen when itâs no longer visible, including when you switch between tabs. When a tab screen gets rebuilt, it loses its state because Flutter doesnât store it unless explicitly told to do so.
This is where the concept of preserving state comes in. When you switch tabs, you want Flutter to keep track of where the user left off.
| The Key: AutomaticKeepAliveClientMixin
To solve this issue, weâll use Flutterâs AutomaticKeepAliveClientMixin
. This mixin allows the state of a widget to be preserved when the widget is not visible (like when the user switches tabs).
How Does It Work?
The AutomaticKeepAliveClientMixin
tells Flutter to keep the state of a tabâs content alive even when the tab isnât currently active.
Letâs break down how to implement this in your app step by step.
Step-by-Step Implementation
1. Basic TabBar Setup
Before diving into preserving the state, letâs first create a basic TabBar
with some tabs. Here's a simple example:
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: HomePage(),
);
}
}
class HomePage extends StatefulWidget {
@override
_HomePageState createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> with SingleTickerProviderStateMixin {
late TabController _tabController;
@override
void initState() {
super.initState();
_tabController = TabController(length: 3, vsync: this);
}
@override
void dispose() {
_tabController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('TabBar Example'),
bottom: TabBar(
controller: _tabController,
tabs: [
Tab(icon: Icon(Icons.home), text: 'Home'),
Tab(icon: Icon(Icons.person), text: 'Profile'),
Tab(icon: Icon(Icons.settings), text: 'Settings'),
],
),
),
body: TabBarView(
controller: _tabController,
children: [
HomeTab(),
ProfileTab(),
SettingsTab(),
],
),
);
}
}
In this basic example, we have three tabs: Home, Profile, and Settings. Each tab shows a different widget. However, the state is not preserved when switching between tabs.
2. Add AutomaticKeepAliveClientMixin
to Keep Tab State Alive
Now, letâs modify the HomeTab
, ProfileTab
, and SettingsTab
to preserve their state when switching between tabs.
Weâll do this by using AutomaticKeepAliveClientMixin
in each of the tab widgets.
Hereâs how you can modify one of the tabs (letâs take HomeTab
as an example):
class HomeTab extends StatefulWidget {
@override
_HomeTabState createState() => _HomeTabState();
}
class _HomeTabState extends State<HomeTab> with AutomaticKeepAliveClientMixin {
int _counter = 0;
@override
Widget build(BuildContext context) {
super.build(context); // Required to make sure the keep-alive functionality works
return Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
'You have pressed the button this many times:',
),
Text(
'$_counter',
style: Theme.of(context).textTheme.headline4,
),
ElevatedButton(
onPressed: () {
setState(() {
_counter++;
});
},
child: Text('Increment Counter'),
),
],
),
);
}
@override
bool get wantKeepAlive => true; // Tells Flutter to keep the state alive
}
Breakdown:
- We extend
AutomaticKeepAliveClientMixin
to the tabâs state class (_HomeTabState
). - In the
build
method, we callsuper.build(context)
to ensure the mixin works properly. - Finally, we override the
wantKeepAlive
getter to returntrue
, telling Flutter to preserve the widgetâs state.
3. Repeat for Other Tabs
Now, apply the same changes to the ProfileTab
and SettingsTab
.
4. Done!
Thatâs it! Now youâve successfully preserved the state of your tabs in Flutter. Your users can switch between tabs without losing their progress, and youâve significantly improved the UX of your app.
| Letâs Implement this into our Noted App
1. Implement AutomaticKeepAliveClientMixin
in Your Screens
Next, letâs modify our MonthlyScreen
and DailyScreen
to use AutomaticKeepAliveClientMixin
.
MonthlyScreen
Hereâs how you can implement it in the MonthlyScreen:
class MonthlyScreen extends StatefulWidget {
@override
_MonthlyScreenState createState() => _MonthlyScreenState();
}
class _MonthlyScreenState extends State<MonthlyScreen> with AutomaticKeepAliveClientMixin {
@override
Widget build(BuildContext context) {
super.build(context); // Need to call super.build for AutomaticKeepAliveClientMixin to work
return Scaffold(
appBar: AppBar(
title: Text('Monthly Tasks'),
),
body: Center(
child: Text('Monthly Tasks Content'),
),
);
}
@override
bool get wantKeepAlive => true; // This ensures the state is preserved
}
DailyScreen
And similarly, for the DailyScreen:
import 'package:flutter/material.dart';
class DailyScreen extends StatefulWidget {
@override
_DailyScreenState createState() => _DailyScreenState();
}
class _DailyScreenState extends State<DailyScreen> with AutomaticKeepAliveClientMixin {
@override
Widget build(BuildContext context) {
super.build(context); // Need to call super.build for AutomaticKeepAliveClientMixin to work
return Scaffold(
appBar: AppBar(
title: Text('Daily Tasks'),
),
body: Center(
child: Text('Daily Tasks Content'),
),
);
}
@override
bool get wantKeepAlive => true; // This ensures the state is preserved
}
2. Explanation
Import Necessary Packages
- Make sure you have all the necessary packages imported. For
MonthlyScreen
, we're usingfluttertoast
,gap
,hive_flutter
, and some custom packages and models. ForDailyScreen
, the basic Flutter material package is enough.
Use AutomaticKeepAliveClientMixin
- We mix in
AutomaticKeepAliveClientMixin
into our state classes (_MonthlyScreenState
and_DailyScreenState
). This mixin provides thewantKeepAlive
property, which we set totrue
to preserve the state of these screens.
Call super.build(context)
- Inside the
build
method of each screen, we callsuper.build(context)
. This is necessary for the mixin to function properly and ensure the state is retained.
| Conclusion
And there you have it! Now your Flutter TabBar
wonât reset the state when switching between tabs. This simple trick can enhance your app's performance and keep your users happy by maintaining their data and interactions across tabs.
I hope this helps you in your Flutter journey! If you have any questions or run into any issues, feel free to drop a comment below, and Iâll be happy to help.
Until next time, happy coding! đ
| đ Join the Journey!
Weâve built an amazing todo app, âNoted App,â together, but the adventure doesnât stop here. You can checkout the repository on GitHub and follow along day by day to complete the project with us in this open-source endeavor. đđ»
đ Explore the GitHub Repository:
Dive into the code, contribute, and collaborate with other developers. Letâs build something great together.
| đ Enjoyed this tutorial?
For more tips, tutorials, and insights into Flutter, be sure to follow my Medium blog! Stay connected, and letâs continue building amazing things together.
This is just Part 28: Ping me on other platforms⊠tooâŠ.
đ Follow me:
- Medium:- Hemant Kumar Prajapati đ§
- Githubđ»:- Hemantpra389 đ§
- LinkedIn :- Hemant Prajapati đ§
Happy coding! đ !! Happy Flutter !!
đŹ Comment Section is Open!
Share your thoughts or ask questions below.
đ Applaud if you enjoyed this!
Your claps help others find this content.
â Follow for more!
Stay updated with more tips and tutorials.
đż Thank you for reading! If you liked this post and want to support me, you can buy me a coffee here đ