kamranbekirovyz
kamranbekirovyz

Reputation: 1321

How to set Provider's data to data that stored in SharedPreferences in Flutter?

I store bool isDarkTheme variable in my General provider class, I can acces it whenever I want.

The thing I want to do is to save that theme preference of user and whenever user opens app again, instead of again isDarkThem = false I want it to load from preference that I stored in SharedPreferences.

Here is my code of General provider: (I guess it is readable)

import 'package:shared_preferences/shared_preferences.dart';

class General with ChangeNotifier {
  bool isDarkTheme = false;

  General() {
    loadDefaultTheme();
  }

  void loadDefaultTheme() async {
    SharedPreferences prefs = await SharedPreferences.getInstance();
    isDarkTheme = prefs.getBool("is_dark_theme") ?? false;
  }

  void reverseTheme() {
    isDarkTheme = !isDarkTheme;
    notifyListeners();
    saveThemePreference(isDarkTheme);
  }

  void saveThemePreference(bool isDarkTheme) async {
    SharedPreferences prefs = await SharedPreferences.getInstance();
    prefs.setBool("is_dark_theme", isDarkTheme);
  }
}

Upvotes: 1

Views: 987

Answers (1)

Hieu Pham
Hieu Pham

Reputation: 236

Dart does not support async constructors so I think we should take another approach here. I usually create a splash screen (or loading screen, whatever you call it) to load all basic data right after the app is opened.

But if you only want to fetch theme data, you can use the async/await pair in main method:

void main() async {
  WidgetsFlutterBinding.ensureInitialized(); // this line is needed to use async/await in main()

  final prefs = await SharedPreferences.getInstance();
  final isDarkTheme = prefs.getBool("is_dark_theme") ?? false;

  runApp(MyApp(isDarkTheme));
}

After that, we can pass that piece of theme data to the General constructor:

class MyApp extends StatelessWidget {
  final bool isDarkTheme;

  MyApp(this.isDarkTheme);

  @override
  Widget build(BuildContext context) {
    return ChangeNotifierProvider(
      create: (_) => General(isDarkTheme), // pass it here
      child: MaterialApp(
        home: YourScreen(),
      ),
    );
  }
}

We should change a bit in the General class as well, the loadDefaultTheme method is left out.

class General with ChangeNotifier {
  bool isDarkTheme;

  General(this.isDarkTheme);

 // ...
}

Upvotes: 1

Related Questions