Home > OS >  save theme change settings
save theme change settings

Time:03-19

I'm setting up my app to be able to switch the app's theme color from white to dark. I installed the provider package and when switching between pages, the settings are saved. But if the page is refreshed or closed and reopened, the settings are lost. How can I fix this? I leave the switching code below, but if you need any way to answer my question, let me know

main.dart

    void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) => ChangeNotifierProvider(
      create: (context) => ThemeProvider(),
      builder: (context, _) {
        
        final themeProvider = Provider.of<ThemeProvider>(context);
        return MaterialApp(
            debugShowCheckedModeBanner: false,
            themeMode: themeProvider.themeMode,
            theme: MyThemes.lightTheme,
            darkTheme: MyThemes.darkTheme,
            initialRoute: '/',
            routes: {
              '/': (context) => LoginPage(),
              '/profile-user': (context) => (ProfileUser()),
            });
      });
}

change_button.dart

import 'package:flutter/material.dart';
import 'package:itda_fe_mobile/theme_provider.dart';
import 'package:provider/provider.dart';

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

  @override
  Widget build(BuildContext context) {
    final themeProvider = Provider.of<ThemeProvider>(context);

    return Switch.adaptive(
      value: themeProvider.isDarkMode,
      onChanged: (value) {
        final provider = Provider.of<ThemeProvider>(context, listen: false);
        provider.toggleTheme(value);
      },
    );
  }
}

theme_provider.dart

    class ThemeProvider extends ChangeNotifier {
  ThemeMode themeMode = ThemeMode.system;

  bool get isDarkMode {
    if (themeMode == ThemeMode.system) {
      final brightness = SchedulerBinding.instance?.window.platformBrightness;
      return brightness == Brightness.dark;
    } else {
      return themeMode == ThemeMode.dark;
    }
  }

  void toggleTheme(bool isOn) {
    themeMode = isOn ? ThemeMode.dark : ThemeMode.light;
    notifyListeners();
  }
}

class MyThemes {
  static final darkTheme = ThemeData(
    scaffoldBackgroundColor: Colors.grey.shade900,
    primaryColor: Colors.black,
    colorScheme: ColorScheme.dark(),
    iconTheme: IconThemeData(color: Colors.purple.shade200, opacity: 0.8),
  );

  static final lightTheme = ThemeData(
    scaffoldBackgroundColor: Colors.white,
    primaryColor: Colors.white,
    colorScheme: ColorScheme.light(),
    iconTheme: IconThemeData(color: Colors.red, opacity: 0.8),
  );
}

CodePudding user response:

Original Answer

Settings like these can be stored in the SharedPreferences of the app. Take a look at the package: https://pub.dev/packages/shared_preferences

To install it, you can copy its installation line to your pubspec.yaml file, or run `pub add'.

flutter pub add shared_preferences

To use it, you can add some code where you currently switch your theme.

// add this code to get an instance and set the new value of isDarkMode
SharedPreferences prefs = await SharedPreferences.getInstance();
await prefs.setBool('isDarkMode', value);

Then when you start your app (when/before you initialize your provider), you can read the value from the shared preferences and use that.

SharedPreferences prefs = await SharedPreferences.getInstance();
bool initialValue = prefs.getBool('isDarkMode');

Full example with your code

// Main is now an async function, so we can call SharedPreferences.getInstance()
void main() async {
  // Before starting the app, we want to check in the settings whether we were using dark mode or not in the last session

  // Before calling any plugin, we need to make sure the Widget binding is initialized (leaving this out will crash the app!)
  WidgetsFlutterBinding.ensureInitialized();

  // We get the initial isDarkMode from the settings or otherwise just the system theme mode
  SharedPreferences prefs = await SharedPreferences.getInstance();
  bool initialIsDarkMode = prefs.getBool('isDarkMode') ?? ThemeMode.system == ThemeMode.dark;

  // We pass down this boolean value to the app
  runApp(MyApp(initialIsDarkMode));
}


class MyApp extends StatelessWidget {
  // The boolean value is stored in the Widget
  final bool initialIsDarkMode;

  const MyApp(this.initialIsDarkMode, {key}) : super(key: key);

  @override
  Widget build(BuildContext context) => ChangeNotifierProvider(
      // We now pass down this boolean to the ThemeProvider, so it knows what to start with
      create: (context) => ThemeProvider(initialIsDarkMode),
      builder: (context, _) {
        ...
      },
  );

Then in ThemeProvider:

class ThemeProvider extends ChangeNotifier {
  ThemeMode themeMode;

  // Constructor which takes in the bool, and initializes the themeMode accordingly
  ThemeProvider(bool initialIsDarkMode)
      : themeMode = initialIsDarkMode ? ThemeMode.dark : ThemeMode.light;

  ...

  void toggleTheme(bool isOn) async {
    themeMode = isOn ? ThemeMode.dark : ThemeMode.light;

    // also store it in the preferences (in case the app is closed after this)
    SharedPreferences prefs = await SharedPreferences.getInstance();
    await prefs.setBool('isDarkMode', isOn);

    notifyListeners();
  }

  ...
}
  • Related