A Flutter developer toggling dark mode on a smartphone UI with coding elements in the background.
Complete Step-by-Step Tutorial with Code, SEO Tips, and Best Practices
📌 Table of Contents
🔰 Introduction: Why App Settings & Flags Matter
In the world of modern mobile apps, personalisation and persistent user preferences are critical. Whether it's toggling dark mode, saving login status, or onboarding status—app flags and settings can drastically improve user experience.
One of the simplest and most efficient ways to persist lightweight data in Flutter is by using SharedPreferences. In this detailed guide, we’ll explore how to use SharedPreferences in Flutter to store app settings and flags, helping you build scalable, responsive, and user-centric applications.
🧠 What is SharedPreferences in Flutter?
SharedPreferences is a key-value based storage solution that allows apps to store simple data types like:
-
Strings
-
Integers
-
Booleans
-
Doubles
-
String lists
It's backed by NSUserDefaults on iOS and SharedPreferences on Android, ensuring native support and speed.
✅ When & Why to Use SharedPreferences
Use SharedPreferences for:
-
First-time launch flags (e.g. hasSeenOnboarding)
-
Theme preferences (e.g. darkModeEnabled)
-
User tokens or IDs
-
Feature toggles
-
App settings & configurations
Avoid using it for large or sensitive data. For secure or complex data, consider using flutter_secure_storage
or databases like Hive
or SQLite
.
🛠️ Installing the shared_preferences
Package
Add the package to your pubspec.yaml
file:
dependencies:
flutter:
sdk: flutter
shared_preferences: ^2.2.2
Then run:
flutter pub get
This package is well-maintained and endorsed by the Flutter team.
⚙️ Initialising SharedPreferences – Step-by-Step
Before accessing or saving any data, initialise SharedPreferences:
import 'package:shared_preferences/shared_preferences.dart';
Future<void> initialisePreferences() async {
final prefs = await SharedPreferences.getInstance();
// You can now use prefs to read/write
}
You should typically initialise this in your app’s main()
or inside a SettingsProvider
for better state management.
💾 Saving Data: Set Flags and Preferences
Future<void> saveDarkModeFlag(bool isDarkMode) async {
final prefs = await SharedPreferences.getInstance();
await prefs.setBool('darkMode', isDarkMode);
}
Other supported methods:
prefs.setString('userName', 'John');
prefs.setInt('launchCount', 5);
prefs.setDouble('volume', 0.8);
prefs.setStringList('items', ['item1', 'item2']);
📥 Retrieving Data: Get Values When Needed
Future<bool> getDarkModeFlag() async {
final prefs = await SharedPreferences.getInstance();
return prefs.getBool('darkMode') ?? false;
}
Defaults are important to avoid nulls.
✅ Best Practice: Always provide fallback values (??
operator) to prevent app crashes.
🗑️ Deleting Preferences: Resetting Flags
You can remove a specific setting:
prefs.remove('darkMode');
Or clear everything:
prefs.clear();
Use this when the user logs out or resets the app.
🌙 Practical Use Case: Dark Mode Toggle with SharedPreferences
Here’s how to implement a theme toggle that persists the user’s preference:
1. Toggle Button:
Switch(
value: isDarkMode,
onChanged: (value) {
setState(() {
isDarkMode = value;
saveDarkModeFlag(value);
});
},
)
2. Retrieve Preference on App Start:
void loadThemePreference() async {
final prefs = await SharedPreferences.getInstance();
setState(() {
isDarkMode = prefs.getBool('darkMode') ?? false;
});
}
3. Apply Theme in MaterialApp
:
MaterialApp(
theme: isDarkMode ? ThemeData.dark() : ThemeData.light(),
)
This improves user experience and shows a deep understanding of Flutter UI persistence.
🧩 How to Create a Responsive UI That Adapts to Settings
Responsive design isn’t just about screen size—it includes theme responsiveness and user choices.
Here’s how to make your app UI adapt to the dark mode flag:
Widget build(BuildContext context) {
final brightness = MediaQuery.of(context).platformBrightness;
final isDarkTheme = brightness == Brightness.dark || isDarkMode;
return Scaffold(
backgroundColor: isDarkTheme ? Colors.black : Colors.white,
body: Center(
child: Text(
'Welcome!',
style: TextStyle(
color: isDarkTheme ? Colors.white : Colors.black,
),
),
),
);
}
This keeps your Flutter UI responsive and personal.
🧠 Expert Views & Best Practices
🔹 Reso Coder, a well-known Flutter expert, recommends using SharedPreferences only for "small, persistent values that don't need encryption".
🔹 According to the Flutter Devs team, “Don’t store complex data in SharedPreferences. Use it for flags, counters, and preferences.”
✅ Best Practices:
-
Always handle null values.
-
Use constants for keys:
const String darkModeKey = "darkMode";
-
Avoid calling
SharedPreferences.getInstance()
repeatedly. Use dependency injection or caching. -
Use it in combination with state management (
Provider
,Riverpod
, etc.) for optimal architecture.
⚠️ Common Mistakes and How to Avoid Them
Mistake | Effect | Solution |
---|---|---|
Repeatedly calling getInstance() |
App slowdown | Initialise once |
Storing complex objects | Data loss/crash | Use Hive or SQLite |
Not handling null | App crash | Use ?? fallback |
Saving sensitive data | Security risk | Use secure storage |
✅ Conclusion
Using SharedPreferences in Flutter is a powerful yet simple way to handle persistent app settings and flags. Whether you're implementing dark mode, saving onboarding status, or toggling features—this method is lightweight, efficient, and easy to use.
Combine SharedPreferences with responsive UI design and good coding practices, and you’ll build user-friendly, fast-loading Flutter apps that remember your users and delight them with personalised experiences.
📝 Disclaimer
While I am not a professional Flutter developer or UI/UX
expert, I have thoroughly researched this topic using official Flutter
documentation, expert opinions, and industry best practices to compile this
guide. This post aims to provide helpful insights and practical examples to
support your learning journey. However, for advanced or complex Flutter
projects, seeking advice from experienced developers is always recommended to
ensure best results.
Your suggestions and views on Flutter responsive design
are welcome—please share below!
Previous Post 👉 Implementing Offline Mode with Sync in Flutter Apps
Next Post 👉 Handling Permissions Across Android & iOS in Flutter
