2

I implemented dark mode to my code.

The application opens in light mode true.

My main code

void main() async {
  runApp(
    ChangeNotifierProvider(
      builder: (_) => ThemeProvider(isLightTheme: true),
      child: MyApp(),
    ),
  );
}

From here, the user changes the theme and I save the current setting with sharedpereferences.

class ThemeProvider with ChangeNotifier {
  bool isLightTheme;
  ThemeProvider({this.isLightTheme});

  ThemeData get getThemeData => isLightTheme ? lightTheme : darkTheme;


  addStringToSF(bool value) async {
    SharedPreferences prefs = await SharedPreferences.getInstance();
    prefs.setBool('boolValue', value);
    return prefs.getBool('boolValue');
  }

  set setThemeData(bool val) {
    if (val) {
      isLightTheme = true;
    } else {
      isLightTheme = false;
    }
    addStringToSF(isLightTheme);
    notifyListeners();
  }
}

I want the application to be opened with the value in my sharedpreferences data. How can I do that.

thekavak
  • 199
  • 11

2 Answers2

1

On your main function you can obtain the SharedPreferences instance and look for the desired bool value:

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  SharedPreferences prefs = await SharedPreferences.getInstance();
  bool storedValue = prefs.getBool('boolValue');
  runApp(
    ChangeNotifierProvider(
      builder: (_) => ThemeProvider(isLightTheme: storedValue),
      child: MyApp(),
    ),
  );
}

Don't forget to import your SharedPreferences on top of the main file:

import 'package:shared_preferences/shared_preferences.dart';

Don't forget that since you are using an async main function you have to use the Ensure Initialized method before the "runApp()" call:

WidgetsFlutterBinding.ensureInitialized();

Naslausky
  • 3,443
  • 1
  • 14
  • 24
  • It gave me an error. `If you're running an application and need to access the binary messenger before `runApp()` has been called (for example, during plugin initialization), then you need to explicitly call the `WidgetsFlutterBinding.ensureInitialized()` first.` Then I added WidgetsFlutterBinding.ensureInitialized() method to first line. – thekavak Jul 24 '20 at 19:09
  • New an error. 'I/flutter (26446): ══╡ EXCEPTION CAUGHT BY WIDGETS LIBRARY ╞═══════════════════════════════════════════════════════════ I/flutter (26446): The following _TypeError was thrown building MyApp(dirty, dependencies: I/flutter (26446): [InheritedProvider]): I/flutter (26446): type 'Future' is not a subtype of type 'bool'' – thekavak Jul 24 '20 at 19:11
  • 1
    @thekavak You need to add the following line in main function: ```WidgetsFlutterBinding.ensureInitialized();```. I eddited my answer to account for that. – Naslausky Jul 24 '20 at 19:13
0

'If you want to use dark/light mode in your app according to your System mode assuming the end devices support that - the MaterialApp has a theme attribute which represents the the 'System light theme' where as the darkTheme Attribute represents the 'System dark mode'. I created a class called AppTheme where i initialise 2 static final ThemeData objects:

class AppTheme {
  static final ThemeData lightTeme = ThemeData(
      //Theme light
      brightness: Brightness.light,
      primaryColor: Colors.white,
      accentColor: Colors.black,
      inputDecorationTheme: InputDecorationTheme(
          labelStyle: TextStyle(color: Colors.black),
          focusedBorder: OutlineInputBorder(
              borderRadius: BorderRadius.circular(25.0),
              borderSide: BorderSide(color: Colors.black)),
          enabledBorder: OutlineInputBorder(
              borderRadius: BorderRadius.circular(25.0),
              borderSide: BorderSide(color: Colors.black))),
      buttonTheme: ButtonThemeData(
        shape: RoundedRectangleBorder(
            borderRadius: BorderRadius.circular(18.0),
            side: BorderSide(color: Colors.black)),
      ),
      // This makes the visual density adapt to the platform that you run
      // the app on. For desktop platforms, the controls will be smaller and
      // closer together (more dense) than on mobile platforms.
      visualDensity: VisualDensity.adaptivePlatformDensity);

  static final ThemeData darkTheme = ThemeData(
      brightness: Brightness.dark,
      primaryColor: Colors.black,
      accentColor: Colors.white,
      inputDecorationTheme: InputDecorationTheme(
          labelStyle: TextStyle(color: Colors.white),
          focusedBorder: OutlineInputBorder(
              borderRadius: BorderRadius.circular(25.0),
              borderSide: BorderSide(color: Colors.white)),
          enabledBorder: OutlineInputBorder(
              borderRadius: BorderRadius.circular(25.0),
              borderSide: BorderSide(color: Colors.white))),
      buttonTheme: ButtonThemeData(
        shape: RoundedRectangleBorder(
            borderRadius: BorderRadius.circular(18.0),
            side: BorderSide(color: Colors.white)),
      ),
      
      //Button Theme Light
      visualDensity: VisualDensity.adaptivePlatformDensity);
}

you can access them in your MaterialApp widget:

@override
  Widget build(BuildContext context) {
    return MaterialApp(
      localizationsDelegates: [
        S.delegate,
        GlobalMaterialLocalizations.delegate,
        GlobalWidgetsLocalizations.delegate
      ],
      supportedLocales: S.delegate.supportedLocales,
      theme: AppTheme.lightTeme,
      darkTheme: AppTheme.darkTheme,
      home: HomeworkDiaryApp(),
    );
  }

You dont have to worry about your app handling changes. It will do it automatically once you change the system dark mode (Testing on my real device samsung galaxy s8 works like a charm)

I think its paradoxical to implement an 'only in app dark and light mode' when all the phones people mostly use today have a system dark or light mode!

Dharman
  • 30,962
  • 25
  • 85
  • 135
jksevend
  • 418
  • 5
  • 18
  • Thank you. I want to control manually and I can do this but I can not start from the selected feature light or dark – thekavak Jul 24 '20 at 19:13