Provider in Flutter doesn't return at the first build of App. In my app you can select the primary color of the app. So when I make it color 2 for example (int represent a color) I save it using Shared Preferences and use it in every page and widget using provider. Easy enough! But at the first build of the app it doesn't fetch the color. Images for beter understanding:
When app is launched:
When I use the NavBar:
Hopefully you can understand the problem with the use of the images. Can anyone help with it fetching the color immediately at the first build of the app.
This is the provider for the switching of the colors:
class ColorProvider with ChangeNotifier {
int _selectedColor = 0;
Color _mainColor = Colors.blue;
ColorProvider() {
_getColor();
}
int get selectedColor => _selectedColor;
set selectedColor(int index) {
_selectedColor = index;
_saveColor();
notifyListeners();
}
Color get mainColor => _mainColor;
Future<void> _saveColor() async {
SharedPreferences prefs = await SharedPreferences.getInstance();
await prefs.setInt('_selectedColorKey', _selectedColor);
}
Future<void> _getColor() async {
SharedPreferences prefs = await SharedPreferences.getInstance();
final savedSelectedColor = prefs.getInt('_selectedColorKey');
if (savedSelectedColor != null) {
_selectedColor = savedSelectedColor;
}
}
// This code can be used in another widget the provider and prefs only
// saves an int so with this you can choose (this isn't too important)
_getMainClr(int no) {
switch (no) {
case 0:
_mainColor = blueClr;
return blueClr;
case 1:
_mainColor = tifBlueClr;
return tifBlueClr;
case 2:
_mainColor = yellowClr;
return yellowClr;
default:
_mainColor = blueClr;
return blueClr;
}
}
}
I tried to implement this code so that it can fetch the getPrefs
at the start but the color Provider
above pretty much does this already but this code was worth a try.
@override
void initState() {
super.initState();
getPrefs();
}
Future<void> getPrefs() async {
//Get the int selected Color
setState(() {});
}
The problem you have, is due to the asynchronous nature of getting data from SharedPreferences.for solving this issue you can create a method named init()
in ColorProvider
and call it like this:
class ColorProvider with ChangeNotifier {
int _selectedColor = 0;
Color _mainColor = Colors.blue;
bool _isInitialized = false;
int get selectedColor => _selectedColor;
set selectedColor(int index) {
_selectedColor = index;
_saveColor();
notifyListeners();
}
Color get mainColor => _mainColor;
Future<void> init() async {
await _getColor();
_isInitialized = true;
notifyListeners();
}
Future<void> _saveColor() async {
SharedPreferences prefs = await SharedPreferences.getInstance();
await prefs.setInt('_selectedColorKey', _selectedColor);
}
Future<void> _getColor() async {
SharedPreferences prefs = await SharedPreferences.getInstance();
final savedSelectedColor = prefs.getInt('_selectedColorKey');
if (savedSelectedColor != null) {
_selectedColor = savedSelectedColor;
}
}
// the rest of your code
}
and call init()
like this:
@override
void initState() {
super.initState();
Provider.of<ColorProvider>(context,listen:false).init();
}
happy coding...