prefnotifiers 0.0.3
prefnotifiers: ^0.0.3 copied to clipboard
Represents shared preferences as ValueNotifier objects. Reads and writes occur asynchronously in the background.
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.
Why use PrefItem? #
Suppose, we have parameter, that can be read with shared_preferences like that:
final prefs = await SharedPreferences.getInstance();
int paramValue = await prefs.getInt("TheParameter");
There are two lines of problem:
-
This code is asynchronous. We cannot use such code directly when building a widget
-
The
paramValuedoes not reflect the parameter changes
Instead, we suggest using the new PrefItem class for accessing the parameter:
final param = PrefItem<int>(SharedPrefsStorage(), "TheParameter");
paramobject can be used as the only representation of"TheParameter"in the whole programparam.valueallows indirectly read and write the shared preference value without getting out of syncWidget build(_)methods can access value without relying onFutureBuilderparam.addListenermakes it possible to track changes of the value
What is PrefItem? #
PrefItem serves as a model for an individual parameter stored in shared preferences.
PrefItem.value provides the best value we have for the moment. The actual read/write operations happen asynchronously in background.
PrefItem<int> reads/writes an int value, PrefItem<String> reads/writes a String and so on.
How to use PrefItem? #
Create PrefItem #
final param = PrefItem<int>(SharedPrefsStorage(), "TheParameter");
Read PrefItem value #
Reading is is not finished yet. But we already can access param.value. By default, it returns null.
We can use it in synchronous code:
Widget build(BuildContext context) {
if (param.value==null)
return Text("Not initialized yet");
else
return Text("Value is ${param.value}");
}
Since PrefItem inherits from the ValueNotifier class, we can automatically rebuild the widget when the param will be available:
Widget build(BuildContext context) {
return ValueListenableBuilder(
valueListenable: param,
builder: (BuildContext context, int value, Widget child) {
if (value==null)
return Text("Not initialized yet");
else
return Text("Value is $value");
});
}
Write PrefItem value #
The code above will also rebuild the widget when value is changed. Let's change the value in a button callback:
onTap: () {
// param.value is 3, shared preferences value is 3
param.value += 1;
param.value += 1;
// param.value 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
}
What is PrefsStorage? #
Each PrefItem relies on a PrefsStorage that actually stores data.
final itemInSharedPreferences = PrefItem<int>(SharedPrefsStorage(), ...);
final itemInRam = PrefItem<int>(RamPrefsStorage(), ...);
final itemInFile = PrefItem<int>(CustomJsonPrefsStorage(), ...);
Normally same instance of PrefsStorage is used by multiple PrefItem objects:
final storage = SharedPrefsStorage();
final a = PrefItem<String>(storage, "nameA");
final b = PrefItem<double>(storage, "nameB");
-
SharedPrefsStoragestores preferences in platform-dependent shared_preferences -
RamPrefsStoragestores preferences in RAM. This class is mostly useful for testing -
PrefsStorageis an abstract base class describing a storage. A descendant should be able of reading and writing named values of typesint,double,String,StringListandDateTime