Home > other >  Flutter theme modes
Flutter theme modes

Time:01-24

I have a project I'm working on and I want to switch it to the three modes, light, dark, and according to the system.

I want an add-on code to do this in addition to saving the mode to be selected, away from any state management, I have put a simple code with three buttons for each case.

Material app

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      theme: ThemeData(scaffoldBackgroundColor: Colors.white),
      darkTheme: ThemeData(scaffoldBackgroundColor: Colors.black),
      themeMode: ThemeMode.system,
      home: const HomePage(),
    );
  }
}

HomePage

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: [
          ElevatedButton(onPressed: (){}, child: const Text('Dark mode')),
          ElevatedButton(onPressed: (){}, child: const Text('Light mode')),
          ElevatedButton(onPressed: (){}, child: const Text('System mode')),
        ],
      )
    );
  }
}

CodePudding user response:

here is the code to do it

class MyApp extends StatefulWidget {
  const MyApp({super.key});

  @override
  State<MyApp> createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  ThemeMode mode = ThemeMode.dark;
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      theme: ThemeData(scaffoldBackgroundColor: Colors.white),
      darkTheme: ThemeData(scaffoldBackgroundColor: Colors.black),
      themeMode: mode,
      home: Scaffold(
        body: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            ElevatedButton(
                onPressed: () {
                  setState(() {
                    mode = ThemeMode.dark;
                  });
                },
                child: const Text('Dark mode')),
            ElevatedButton(
              onPressed: () {
                setState(() {
                  mode = ThemeMode.light;
                });
              },
              child: const Text('Light mode'),
            ),
            ElevatedButton(
              onPressed: () {
                setState(() {
                  mode = ThemeMode.system;
                });
              },
              child: const Text('System mode'),
            ),
          ],
        ),
      ),
    );
  }
}

and here is the result enter image description here

Edit: if you don't want to merge these classes you can use it separate as well like this

Material App

class MyApp extends StatefulWidget {
  const MyApp({super.key});

  @override
  State<MyApp> createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  ThemeMode mode = ThemeMode.dark;
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      theme: ThemeData(scaffoldBackgroundColor: Colors.white),
      darkTheme: ThemeData(scaffoldBackgroundColor: Colors.black),
      themeMode: mode,
      home: HomePage(
        changeThemeToDark: () {
          setState(() {
            mode = ThemeMode.dark;
          });
        },
        changeThemeToLight: () {
          setState(() {
            mode = ThemeMode.light;
          });
          print("changes=d");
        },
        changeThemeToSystem: () {
          mode = ThemeMode.system;
        },
      ),
    );
  }
}

HomePage

class HomePage extends StatelessWidget {
  const HomePage(
      {Key? key,
      required this.changeThemeToDark,
      required this.changeThemeToSystem,
      required this.changeThemeToLight})
      : super(key: key);

  final VoidCallback changeThemeToDark;
  final VoidCallback changeThemeToSystem;
  final VoidCallback changeThemeToLight;
  @override
  Widget build(BuildContext context) {
    return Scaffold(
        body: Column(
      mainAxisAlignment: MainAxisAlignment.center,
      children: [
        ElevatedButton(
            onPressed: () {
              changeThemeToDark();
            },
            child: const Text('Dark mode')),
        ElevatedButton(
            onPressed: () {
              changeThemeToLight();
            },
            child: const Text('Light mode')),
        ElevatedButton(
            onPressed: () {
              changeThemeToSystem();
            },
            child: const Text('System mode')),
      ],
    ));
  }
}

CodePudding user response:

Here's an example of how you an add functionality to your existing code to switch between the three modes and save the selected mode:

  1. Create a new file called theme_manager.dart and add the following code:
 import 'package:shared_preferences/shared_preferences.dart';

class ThemeManager {
  static const _themeModeKey = 'themeMode';

  static const _lightModeValue = 'light';

  static const _darkModeValue = 'dark';

  static const _systemModeValue = 'system';

  static Future<ThemeMode> getSavedThemeMode() async {
    final prefs = await SharedPreferences.getInstance();

    final themeModeString = prefs.getString(_themeModeKey);

    if (themeModeString == _lightModeValue) {
      return ThemeMode.light;
    } else if (themeModeString == _darkModeValue) {
      return ThemeMode.dark;
    } else {
      return ThemeMode.system;
    }
  }

  static Future<void> saveThemeMode(ThemeMode themeMode) async {
    final prefs = await SharedPreferences.getInstance();

    if (themeMode == ThemeMode.light) {
      prefs.setString(_themeModeKey, _lightModeValue);
    } else if (themeMode == ThemeMode.dark) {
      prefs.setString(_themeModeKey, _darkModeValue);
    } else {
      prefs.setString(_themeModeKey, _systemModeValue);
    }
  }
}
  1. In your MyApp widget, change the themeMode property to use the getSavedThemeMode() method:

     class MyApp extends StatelessWidget {
          const MyApp({super.key});
        
          @override
          Widget build(BuildContext context) {
            return MaterialApp(
              debugShowCheckedModeBanner: false,
              theme: ThemeData(scaffoldBackgroundColor: Colors.white),
              darkTheme: ThemeData(scaffoldBackgroundColor: Colors.black),
              themeMode: ThemeManager.getSavedThemeMode(),
              home: const HomePage(),
            );
          }
        }

  1. In your HomePage widget, add the following code to handle the button presses and call the saveThemeMode() method:
class HomePage extends StatelessWidget {
  const HomePage({Key? key}) : super(key: key);

      @override
      Widget build(BuildContext context) {
        return Scaffold(
          body: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: [
              ElevatedButton(
                onPressed: () {
                  ThemeManager.saveThemeMode(ThemeMode.dark);
                  setState(() {});
                },
                child: const Text('Dark mode')
              ),
              ElevatedButton(
                onPressed: () {
                  ThemeManager.saveThemeMode(ThemeMode.light);
                  setState(() {});
                },
                child: const Text('Light mode')
              ),
              ElevatedButton(
                onPressed: () {
                  ThemeManager.saveThemeMode(ThemeMode.system);
                 },
    child: const Text('Light mode')
        )
  • Related