0 purchases
prefnotifiers
prefnotifiers #
This library represents shared_preferences as ValueNotifier objects.
It fits in well with the paradigm of data models. Models make data readily available to widgets.
Reads and writes occur asynchronously in background.
Why use PrefNotifier? #
Suppose, we have parameter, that can be read with shared_preferences like that:
final prefs = await SharedPreferences.getInstance();
int myParamValue = await prefs.getInt("MyParameter");
copied to clipboard
There are two lines of problem:
This code is asynchronous. We cannot use such code directly when building a widget
The paramValue does not reflect the parameter changes
Instead, we suggest using the new PrefNotifier class for accessing the parameter:
final myParam = PrefNotifier<int>("MyParameter");
copied to clipboard
myParam object can be used as the only representation of "MyParameter" in the whole program
myParam.value allows indirectly read and write the shared preference value without getting out of sync
Widget build(_) methods can access value without relying on FutureBuilder
myParam.addListener makes it possible to track changes of the value
What is PrefNotifier? #
PrefNotifier.value provides the best value we have for the moment. The actual read/write operations happen asynchronously in background.
PrefNotifier serves as a model for an individual parameter stored in shared preferences.
Types #
Type
Аlternative to SharedPreferences'
PrefNotifier<bool>
.setBool .getBool .remove
PrefNotifier<int>
.setInt .getInt .remove
PrefNotifier<double>
.setDouble .getDouble .remove
PrefNotifier<String>
.setString .getString .remove
PrefNotifier<List<String>>
.setStringList .getStringList .remove
Basic operations #
PrefNotifier
SharedPreferences
myParam = PrefNotifier<int>('MyParameter')
prefs = await SharedPreferences.getInstance()
myParam.value = 42
await prefs.setInt('MyParameter', 42)
int? x = myParam.value
int? x = await prefs.getInt('MyParameter')
myParam.value = null
await prefs.remove('MyParameter')
But the most great is:
myParam.addListener(() => print('Value changed! New value: ${myParam.value}');
copied to clipboard
How to use PrefNotifier? #
Create #
final myParam = PrefNotifier<int>("MyParameter");
copied to clipboard
Before 1.0.0 and sound null safety it's PrefItem
final myParam = PrefItem<int>(SharedPrefsStorage(), "MyParameter");
copied to clipboard
In newer version of the library PrefItem works as well. PrefNotifier is an easier to use alias.
Read #
Reading is is not finished yet. But we already can access myParam.value. By default, it returns null.
We can use it in synchronous code:
Widget build(BuildContext context) {
if (myParam.value==null)
return Text("Not initialized yet");
else
return Text("Value is ${myParam.value}");
}
copied to clipboard
Since PrefNotifier inherits from the ValueListenable, we can automatically
rebuild the widget when the new value of myParam will be available:
Widget build(BuildContext context) {
return ValueListenableBuilder(
valueListenable: myParam,
builder: (BuildContext context, int? value, Widget child) {
if (value==null)
return Text("Not initialized yet");
else
return Text("Value is $value");
});
}
copied to clipboard
Write #
The code above will also rebuild the widget when value is changed. Let's change the value in a button callback:
onTap: () {
// myParam.value is 3, shared preferences value is 3
myParam.value += 1;
myParam.value += 1;
// myParam.value is already changed to 5
//
// The widget will rebuild momentarily (i.e. on the next frame)
//
// Shared preferences still contain value 3. But asynchronous writing
// already started. It will rewrite value in a few milliseconds
}
copied to clipboard
Load #
For a newly created PrefNotifier the value returns null until the object
reads the actual data from the storage. Asynchronous loading starts
automatically when the object is created.
But what if we want to get the loaded data before doing anything else?
final myParam = PrefNotifier<int>("TheParameter");
await myParam.initialized;
// we waited while the object was reading the data.
// Now myParam.value returns the value from the storage, not default NULL.
// Even if it is NULL, it is a NULL from the storage :)
copied to clipboard
Keep in sync #
Create a single instance of PrefNotifier for a particular
parameter. Only access this parameter with this PrefNotifier instance.
final myParam = PrefNotifier<int>("MyParameter");
myParam.value = 5;
await (await SharedPreferences.getInstance())
.setInt("MyParameter", 10); // DON'T DO THIS
var otherNotifier = PrefNotifier<int>("MyParameter"); // DON'T DO THIS
otherNotifier = 20;
// now the myParam.value is still 5.
// And the myParam has no idea it is changed
copied to clipboard
Test #
To test a program that uses PrefNotifiers, you can populate initial values
the same way, as in the case of using SharedPreferences directly:
TestWidgetsFlutterBinding.ensureInitialized();
SharedPreferences.setMockInitialValues(Map<String, dynamic> values);
copied to clipboard
For personal and professional use. You cannot resell or redistribute these repositories in their original state.
There are no reviews.