Flutter Dark Mode
Implementing beautiful dark themes for better user experience
🌙 What is Dark Mode?
Dark mode provides a darker color scheme that reduces eye strain in low-light environments and saves battery on OLED screens. Flutter makes it easy to implement dark themes that automatically adapt to system preferences or allow users to manually toggle between light and dark modes.
MaterialApp(
theme: ThemeData.light(),
darkTheme: ThemeData.dark(),
themeMode: ThemeMode.system,
home: MyHomePage(),
)
Output (Dark Mode):
Dark Mode Features
System Theme
Follow device theme settings
MaterialApp(
themeMode: ThemeMode.system,
theme: ThemeData.light(),
darkTheme: ThemeData.dark(),
)
Custom Dark Theme
Create custom dark colors
ThemeData.dark().copyWith(
primaryColor: Colors.teal,
scaffoldBackgroundColor:
Color(0xFF121212),
)
Toggle Theme
Switch between themes manually
IconButton(
icon: Icon(Icons.brightness_6),
onPressed: () {
// Toggle theme
},
)
Save Preference
Remember user's theme choice
SharedPreferences prefs =
await SharedPreferences.getInstance();
prefs.setBool('isDark', true);
🔹 Basic Dark Mode Setup
Implement dark mode with system theme detection:
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Dark Mode App',
// Light theme
theme: ThemeData(
brightness: Brightness.light,
primarySwatch: Colors.blue,
scaffoldBackgroundColor: Colors.white,
),
// Dark theme
darkTheme: ThemeData(
brightness: Brightness.dark,
primarySwatch: Colors.blue,
scaffoldBackgroundColor: Color(0xFF121212),
),
// Follow system theme
themeMode: ThemeMode.system,
home: MyHomePage(),
);
}
}
Output:
🔹 Custom Dark Theme
Create a beautiful custom dark theme:
ThemeData darkTheme = ThemeData(
brightness: Brightness.dark,
// Primary colors
primaryColor: Colors.teal,
colorScheme: ColorScheme.dark(
primary: Colors.teal,
secondary: Colors.tealAccent,
surface: Color(0xFF1E1E1E),
background: Color(0xFF121212),
),
// Scaffold
scaffoldBackgroundColor: Color(0xFF121212),
// App bar
appBarTheme: AppBarTheme(
backgroundColor: Color(0xFF1E1E1E),
elevation: 0,
),
// Card
cardTheme: CardTheme(
color: Color(0xFF1E1E1E),
elevation: 2,
),
// Text
textTheme: TextTheme(
bodyLarge: TextStyle(color: Colors.white),
bodyMedium: TextStyle(color: Colors.white70),
),
)
Output:
🔹 Theme Toggle with State
Allow users to manually switch themes:
class MyApp extends StatefulWidget {
@override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State {
ThemeMode _themeMode = ThemeMode.system;
void toggleTheme() {
setState(() {
_themeMode = _themeMode == ThemeMode.light
? ThemeMode.dark
: ThemeMode.light;
});
}
@override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData.light(),
darkTheme: ThemeData.dark(),
themeMode: _themeMode,
home: Scaffold(
appBar: AppBar(
title: Text('Theme Toggle'),
actions: [
IconButton(
icon: Icon(Icons.brightness_6),
onPressed: toggleTheme,
),
],
),
body: Center(child: Text('Toggle theme with button')),
),
);
}
}
Output:
🔹 Detecting Current Theme
Check if dark mode is active in your widgets:
class MyWidget extends StatelessWidget {
@override
Widget build(BuildContext context) {
// Check if dark mode is active
bool isDarkMode = Theme.of(context).brightness == Brightness.dark;
return Container(
color: isDarkMode ? Colors.grey[900] : Colors.white,
child: Text(
'Current theme: ${isDarkMode ? "Dark" : "Light"}',
style: TextStyle(
color: isDarkMode ? Colors.white : Colors.black,
),
),
);
}
}
// Or use MediaQuery
bool isDarkMode = MediaQuery.of(context).platformBrightness == Brightness.dark;
Output:
🔹 Dark Mode Best Practices
Design Tips:
- Use true black sparingly: #121212 is better than #000000 for OLED screens
- Reduce elevation: Lower shadows in dark mode for better visibility
- Adjust colors: Desaturate bright colors to reduce eye strain
- Maintain contrast: Ensure text is readable with sufficient contrast
- Test thoroughly: Check all screens in both light and dark modes
// Good dark mode colors
Color darkBackground = Color(0xFF121212); // Not pure black
Color darkSurface = Color(0xFF1E1E1E); // Slightly lighter
Color darkText = Colors.white; // High contrast
Color darkTextSecondary = Colors.white70; // Lower contrast
// Adjust elevation for dark mode
Card(
elevation: isDarkMode ? 2 : 4,
child: Container(...),
)