0

I am using of provider to change theme in my app. My app initialize first with dark theme.

class ThemeNotifier extends ChangeNotifier {
  final String key = "them";
  SharedPreferences _prefs;
  bool _darkTheme;

  bool get darkTheme => _darkTheme;

  ThemeNotifier() {
    _darkTheme = true;
    _loadFromPrefs();
  }

  toggleTheme() {
    _darkTheme = !_darkTheme;
    _saveToPrefs();
    notifyListeners();
  }

  _loadFromPrefs() async {
    await _initPrefs();
    _darkTheme = _prefs.getBool(key) ?? true;
    notifyListeners();
  }

  _saveToPrefs() async {
    await _initPrefs();
    _prefs.setBool(key, _darkTheme);
  }

  _initPrefs() async {
    if (_prefs == null) _prefs = await SharedPreferences.getInstance();
  }
}

When i changed them to light i call toggleTheme method and i change _darkTheme to false.

I use above codes like this:

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return ChangeNotifierProvider.value(
      value: ThemeNotifier(),
      child: Consumer<ThemeNotifier>(
        builder: (context, notifire, child) {
          child:
          return MaterialApp(
            title: "theme",
            theme: notifire.darkTheme ? dark : light,
            home: HomeScreen(),
          );
        },
      ),
    );
  }
}

but when i change app with light theme and do hot reload application for just a second my app theme is dark and then changed into light mode.

How could i load application without dark mode when i use light mode?that is mean when i change them to light mode i do not want to show dark mode even for a few millisecond ?

Cyrus the Great
  • 5,145
  • 5
  • 68
  • 149
  • Try this ThemeNotifier() { _loadFromPrefs(); } instead of ThemeNotifier() { _darkTheme = true; _loadFromPrefs(); } – Federick Jonathan Feb 23 '20 at 15:13
  • if i do that , i got error I/flutter (10261): The following assertion was thrown building Consumer(dirty, dependencies: I/flutter (10261): [_DefaultInheritedProviderScope]): I/flutter (10261): Failed assertion: boolean expression must not be null @FederickJonathan – Cyrus the Great Feb 23 '20 at 16:09
  • @sayreskabir same problem here. were you able to find a solution? – Karen Oct 16 '20 at 07:26
  • In release mode, It's Ok. – Cyrus the Great Oct 16 '20 at 17:28
  • It looks like you followed this [tutorial](https://codesource.io/building-theme-switcher-using-provider-and-shared-preferences/). I did the same and ran into the very same problem that you have. What have you done in particular to make it work? – tafaust Dec 15 '20 at 16:32
  • For anyone interested, [this answer](https://stackoverflow.com/a/47644516/2402281) gives an indication why the `--release` flag does not cause the error mentioned by OP. – tafaust Dec 16 '20 at 11:19

1 Answers1

0

Regarding

How could i load application without dark mode when i use light mode?that is mean when i change them to light mode i do not want to show dark mode even for a few millisecond ?

When you do not want to have the dark mode shown for a few milliseconds, you have two options:

Option 1: You should wait for the SharedPreferences.getInstance() in a FutureBuilder in your MaterialApp and show a loading screen. The loading screen will be themed with either light or dark unless you theme the loading screen independent of the theme from shared preferences.

Option 2: This option is less user-friendly, because it will block any rendering for said few milliseconds until your shared preferences are loaded. In your main.dart in your main function, you can do the following:

void main() {
    SharedPreferences.getInstance().then(() => runApp(MyApp()));
}

or

void main() async {
    await SharedPreferences.getInstance();
    runApp(MyApp());
}

EDIT 1

Regarding your comment

I/flutter (10261): The following assertion was thrown building Consumer(dirty, dependencies: I/flutter (10261): [_DefaultInheritedProviderScope]): I/flutter (10261): Failed assertion: boolean expression must not be null

I wrote that I had the same error. In my case, that error really originated from somewhere in my build method and it was fairly hard to track it down. I'd suggest to use ChangeNotifierProvider(create: ThemeNotifier(), ... over ChangeNotifierProvider.value(value: ThemeNotifier(), .... For details, please review this very datailed SO answer.

My hunch is that your assertion error stems from the line theme: notifire.darkTheme ? dark : light, in your MaterialApp and it might get fixed if you change your provider to create your change notifier instead of reusing an existing one. Adding the --release flag really is nothing more than a mere workaround to ignore this instability within your app.

tafaust
  • 1,457
  • 16
  • 32