Easy and quick way to add dark mode to a flutter app

Hello there! Thanks for choosing this article to help you add dark mode to your flutter app. arigato gozaimasu!

I wrote this article to help out a colleague who needed this done and I hope it helps others as well!

Steps to add dark mode to your flutter app...

1) Create a styles class where you define your light styles and dark styles e.g app_styles.dart

class AppStyles {
  static ThemeData lightTheme = ThemeData(
    primaryColor: resources.colors.primary,
    scaffoldBackgroundColor: resources.colors.white,
    // ... other light theme properties
  );

  static ThemeData darkTheme = ThemeData(
    primaryColor: resources.colors.primary,
    scaffoldBackgroundColor: resources.colors.black, // or a dark color
    // ... other dark theme properties
    brightness: Brightness.dark,
  );

  // ... rest of the class remains the same
}

2) Update your colors class to define colors for both light and dark mode

class AppColors {
  static const Color primaryLight = Color(0xFF...);
  static const Color primaryDark = Color(0xFF...);

  static const Color backgroundLight = Color(0xFF...);
  static const Color backgroundDark = Color(0xFF...);

  // ... other color definitions

  static Color getPrimaryColor(bool isDarkMode) {
    return isDarkMode ? primaryDark : primaryLight;
  }

  static Color getBackgroundColor(bool isDarkMode) {
    return isDarkMode ? backgroundDark : backgroundLight;
  }

  // ... other getter methods for different colors
}

3) Create a notifier class to manage the theme state e.g theme_notifier.dart

class ThemeNotifier extends ChangeNotifier {
  bool _isDarkMode = false;

  bool get isDarkMode => _isDarkMode;

  void toggleTheme() {
    _isDarkMode = !_isDarkMode;
    notifyListeners();
  }
}

4) Update your main.dart file to use changeNotifierProvider

import 'package:provider/provider.dart';

void main() async {
  WidgetsFlutterBinding.ensureInitialized();

  runApp(
    ChangeNotifierProvider(
      create: (_) => ThemeNotifier(),
      child: MyApp(),
    ),
  );
}

Note: we're using provider package for the app-wide state management solution so run "flutter pub add provider" in your terminal at this point.

5) Update your MyApp widget to listen to theme changes

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Consumer<ThemeNotifier>(
      builder: (context, themeNotifier, child) {
        return MaterialApp(
          title: AppStrings.appName,
          theme: themeNotifier.isDarkMode ? AppStyles.darkTheme : AppStyles.lightTheme,
          // ... rest of your MaterialApp configuration
        );
      },
    );
  }
}

6) Implement a toggle switch in your settings screen

class SettingsScreen extends StatelessWidget {
  const SettingsScreen({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('Settings')),
      body: ListView(
        children: [
          Consumer<ThemeNotifier>(
            builder: (context, themeNotifier, child) {
              return SwitchListTile(
                title: Text('Dark Mode'),
                value: themeNotifier.isDarkMode,
                onChanged: (value) {
                  themeNotifier.toggleTheme();
                },
              );
            },
          ),
          // ... other settings
        ],
      ),
    );
  }
}

Usage...

7) Use the color getters (created in step 2) in your app widgets e.g

Consumer<ThemeNotifier>(
  builder: (context, themeNotifier, child) {
    return Container(
      color: AppColors.getBackgroundColor(themeNotifier.isDarkMode),
      child: Text(
        'Hello',
        style: TextStyle(color: AppColors.getPrimaryColor(themeNotifier.isDarkMode)),
      ),
    );
  },
)

Bonus...

8) Persist user theme preference using sharedPreferences package by updating theme_notifier.dart (created in step 3)

run "flutter pub add shared_preferences" in your terminal at this point.

import 'package:shared_preferences/shared_preferences.dart';

class ThemeNotifier extends ChangeNotifier {
  bool _isDarkMode = false;

  ThemeNotifier() {
    _loadThemePreference();
  }

  bool get isDarkMode => _isDarkMode;

  void toggleTheme() {
    _isDarkMode = !_isDarkMode;
    _saveThemePreference();
    notifyListeners();
  }

  Future<void> _loadThemePreference() async {
    final prefs = await SharedPreferences.getInstance();
    _isDarkMode = prefs.getBool('isDarkMode') ?? false;
    notifyListeners();
  }

  Future<void> _saveThemePreference() async {
    final prefs = await SharedPreferences.getInstance();
    await prefs.setBool('isDarkMode', _isDarkMode);
  }
}

And there you have it! With these steps you can easily and quickly implement dark mode feature in your flutter app.

Thank you!

0
Subscribe to my newsletter

Read articles from Victor Onoja Odoh directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Victor Onoja Odoh
Victor Onoja Odoh

I am a self taught software developer from Nigeria. I enjoy writing technical documents and creating solutions with software.