https://github.com/rtmigo/prefnotifiers_flutter
🗃️ Flutter library representing shared preferences as ValueNotifier objects. Reads and writes occur asynchronously in background
https://github.com/rtmigo/prefnotifiers_flutter
changenotifier flutter shared-preferences state-management
Last synced: 14 days ago
JSON representation
🗃️ Flutter library representing shared preferences as ValueNotifier objects. Reads and writes occur asynchronously in background
- Host: GitHub
- URL: https://github.com/rtmigo/prefnotifiers_flutter
- Owner: rtmigo
- License: bsd-3-clause
- Created: 2021-02-24T18:34:14.000Z (over 5 years ago)
- Default Branch: master
- Last Pushed: 2023-09-23T02:59:21.000Z (almost 3 years ago)
- Last Synced: 2026-02-19T11:42:05.622Z (5 months ago)
- Topics: changenotifier, flutter, shared-preferences, state-management
- Language: Dart
- Homepage: https://pub.dev/packages/prefnotifiers
- Size: 182 KB
- Stars: 2
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- License: LICENSE
Awesome Lists containing this project
README
[](https://pub.dev/packages/prefnotifiers)
[](https://pub.dev/packages/prefnotifiers/score)
[](https://github.com/rtmigo/prefnotifiers.flutter/actions)
# [prefnotifiers](https://github.com/rtmigo/prefnotifiers)
This library represents [shared_preferences](https://pub.dev/packages/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](https://pub.dev/packages/shared_preferences) like that:
``` dart
final prefs = await SharedPreferences.getInstance();
int myParamValue = await prefs.getInt("MyParameter");
```
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:
``` dart
final myParam = PrefNotifier("MyParameter");
```
- `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` | `.setBool` `.getBool` `.remove`
`PrefNotifier` | `.setInt` `.getInt` `.remove`
`PrefNotifier` | `.setDouble` `.getDouble` `.remove`
`PrefNotifier` | `.setString` `.getString` `.remove`
`PrefNotifier>` | `.setStringList` `.getStringList` `.remove`
## Basic operations
PrefNotifier | SharedPreferences
--------------------------------|-----------------------------------------------
`myParam = PrefNotifier('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:
``` dart
myParam.addListener(() => print('Value changed! New value: ${myParam.value}');
```
# How to use PrefNotifier?
## Create
``` dart
final myParam = PrefNotifier("MyParameter");
```
Before 1.0.0 and sound null safety it's PrefItem
``` dart
final myParam = PrefItem(SharedPrefsStorage(), "MyParameter");
```
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:
``` dart
Widget build(BuildContext context) {
if (myParam.value==null)
return Text("Not initialized yet");
else
return Text("Value is ${myParam.value}");
}
```
Since `PrefNotifier` inherits from the `ValueListenable`, we can automatically
rebuild the widget when the new value of `myParam` will be available:
``` dart
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");
});
}
```
## Write
The code above will also rebuild the widget when value is changed. Let's change the value in a button callback:
``` dart
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
}
```
## 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?
``` dart
final myParam = PrefNotifier("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 :)
```
## Keep in sync
Create a **single instance** of PrefNotifier for a **particular
parameter**. Only access this parameter with this PrefNotifier instance.
``` dart
final myParam = PrefNotifier("MyParameter");
myParam.value = 5;
await (await SharedPreferences.getInstance())
.setInt("MyParameter", 10); // DON'T DO THIS
var otherNotifier = PrefNotifier("MyParameter"); // DON'T DO THIS
otherNotifier = 20;
// now the myParam.value is still 5.
// And the myParam has no idea it is changed
```
## Test
To test a program that uses PrefNotifiers, you can populate initial values
the same way, as in the case of using SharedPreferences directly:
``` dart
TestWidgetsFlutterBinding.ensureInitialized();
SharedPreferences.setMockInitialValues(Map values);
```