flutter_mediator_persistence 1.0.0 flutter_mediator_persistence: ^1.0.0 copied to clipboard
A super easy state management package with built in persistence capability, base on the Flutter Mediator Lite.
Flutter Mediator Persistence #
Flutter Mediator | Global Mode + Model Mode | |||
Lite | Global Mode only | |||
Persistence | Lite + Persistence | |||
Example | Logins to a REST server with i18n, theming, persistence and state management. |
Flutter Mediator Persistence is a super easy state management package with built in persistence capability, base on the Flutter Mediator Lite.
Table of Contents #
- Setting up
- Steps
- Recap
- Global Get
- Global Broadcast
- Persistence
- Versions
- Example: Logins to a REST server
- Flutter Widget of the Week: InheritedModel explained
- Changelog
- License
Setting up #
Add the following dependency to pubspec.yaml of your flutter project:
dependencies:
flutter_mediator_persistence: "^1.0.0"
Import flutter_mediator_persistence in files that will be used:
import 'package:flutter_mediator_persistence/mediator.dart';
For help getting started with Flutter, view the online documentation.
Steps #
-
Declare the watched variable with
globalWatch
.
Declare the persistent wathced variable withdefaultVal.globalPersist('key')
Suggest to put the watched variables into a file var.dart and then import it. -
Initial the persistent store with
await initGlobalPersist();
and create the host withglobalHost(child: MyApp())
at the top of the widget tree. -
Create a widget with
globalConsume
orwatchedVar.consume
to register the watched variable to the host to rebuild it when updating. -
Make an update to the watched variable, by
watchedVar.value
orwatchedVar.ob.updateMethod(...)
.
Case 1: Int #
Step 1: var.dart
const DefaultLocale = 'en';
//* Declare the persistent watched variable with `defaultVal.globalPersist('key')`
/// int: 0.globalPersist('intKey');
/// double: 0.0.globalPersist('doubleKey');
/// String: ''.globalPersist('StringKey');
/// bool: false.globalPersist('boolKey');
final locale = DefaultLocale.globalPersist('locale');
final themeIdx = 1.globalPersist('themeIdx');
//* Declare the watched variable with `globalWatch(initialValue)`.
final touchCount = globalWatch(0);
Step 2: main.dart
Future<void> main() async {
//* Step2: Initial the persistent store.
await initGlobalPersist();
runApp(
//* Step2: Create the host with `globalHost`
//* at the top of the widget tree.
globalHost(
child: MyApp(),
),
);
}
Step 3: example/lib/pages/home_page.dart
Scaffold(
appBar: AppBar(title: const Text('Int Demo')),
body: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
const Text('You have pushed the button this many times:'),
//* Step3: Create a widget with `globalConsume` or `watchedVar.consume`
//* to register the watched variable to the host to rebuild it when updating.
globalConsume(
() => Text(
'${touchCount.value}',
style: Theme.of(context).textTheme.headline4,
),
),
// ...
Step 4: example/lib/pages/home_page.dart
FloatingActionButton(
//* Stet4: Make an update to the watched variable.
onPressed: () => touchCount.value++,
tooltip: 'Increment',
child: const Icon(Icons.add),
heroTag: null,
),
Case 2: List #
example/lib/pages/list_page.dart
Step 1: var.dart
//* Step1: Declare the watched variable with `globalWatch` in the var.dart.
//* And then import it in the file.
final data = globalWatch(<ListItem>[]);
Step 3:
return Scaffold(
appBar: AppBar(title: const Text('List Demo')),
//* Step3: Create a widget with `globalConsume` or `watchedVar.consume`
//* to register the watched variable to the host to rebuild it when updating.
body: globalConsume(
() => GridView.builder(
itemCount: data.value.length,
// ...
Step 4:
void updateListItem() {
// ...
//* Step4: Make an update to the watched variable.
//* watchedVar.ob = watchedVar.notify() and then return the underlying object
data.ob.add(ListItem(itemName, units, color));
}
Case 3: Locale setting with Built in Persistence #
Step 1: var.dart
const DefaultLocale = 'en';
//* Declare the persistent watched variable with `defaultVal.globalPersist('key')`
/// int: 0.globalPersist('intKey');
/// double: 0.0.globalPersist('doubleKey');
/// String: ''.globalPersist('StringKey');
/// bool: false.globalPersist('boolKey');
final locale = DefaultLocale.globalPersist('locale');
final themeIdx = 1.globalPersist('themeIdx');
Step 2-1: main.dart
Future<void> main() async {
//* Initial the persistent store.
await initGlobalPersist();
runApp(
//* Step2: Create the host with `globalHost` at the top of the widget tree.
globalHost(child: MyApp())
);
}
Step 2-2: main.dart
//* Initialize the locale with the persistent value.
localizationsDelegates: [
FlutterI18nDelegate(
translationLoader: FileTranslationLoader(
forcedLocale: Locale(locale.value),
fallbackFile: DefaultLocale,
// ...
),
// ...
),
],
Step 3: example/lib/pages/locale_page.dart
return SizedBox(
child: Row(
children: [
//* Step3: Create a widget with `globalConsume` or `watchedVar.consume`
//* to register the watched variable to the host to rebuild it when updating.
//* `watchedVar.consume()` is a helper function to
//* `touch()` itself first and then `globalConsume`.
locale.consume(() => Text('${'app.hello'.i18n(context)} ')),
Text('$name, '),
// ...
],
),
);
Step 4: var.dart
Future<void> changeLocale(BuildContext context, String countryCode) async {
final loc = Locale(countryCode);
await FlutterI18n.refresh(context, loc);
//* Step4: Make an update to the watched variable.
//* The persistent watched variable will update the persistent value automatically.
locale.value = countryCode;
}
Case 4: Scrolling effect #
example/lib/pages/scroll_page.dart
Step 1:
//* Declare the persistent watched variable with `defaultVal.globalPersist('key')`
final scrollOffset = 0.0.globalPersist('ScrollOffsetDemo');
Step 3:
class CustomAppBar extends StatelessWidget {
@override
Widget build(BuildContext context) {
//* Step3: Create a widget with `globalConsume` or `watchedVar.consume`
//* to register the watched variable to the host to rebuild it when updating.
return globalConsume(
() => Container(
color: Colors.black
.withOpacity((scrollOffset.value / 350).clamp(0, 1).toDouble()),
// ...
),
);
}
}
Step 4:
class _ScrollPageState extends State<ScrollPage> {
//* Step4: Initialize the scroll offset with the persistent value.
final _scrollController =
ScrollController(initialScrollOffset: scrollOffset.value);
@override
void initState() {
_scrollController.addListener(() {
//* Step4: Make an update to the watched variable.
scrollOffset.value = _scrollController.offset;
});
super.initState();
}
Recap #
- At step 1,
globalWatch(variable)
creates a watched variable from the variable.
Declare the persistent watched variable withdefaultVal.globalPersist('key')
/// int: 0.globalPersist('intKey');
/// double: 0.0.globalPersist('doubleKey');
/// String: ''.globalPersist('StringKey');
/// bool: false.globalPersist('boolKey');
-
At step 3, create a widget and register it to the host to rebuild it when updating,
useglobalConsume(() => widget)
if the value of the watched variable is used inside the widget;
or usewatchedVar.consume(() => widget)
totouch()
the watched variable itself first and thenglobalConsume(() => widget)
. -
At step 4, update to the
watchedVar.value
will notify the host to rebuild; or the underlying object would be a class, then usewatchedVar.ob.updateMethod(...)
to notify the host to rebuild.watchedVar.ob = watchedVar.notify() and then return the underlying object
.
Global Get #
globalGet<T>({Object? tag})
to retrieve the watched variable from another file.
-
With
globalWatch(variable)
, the watched variable will be retrieved by theType
of the variable, i.e. retrieve byglobalGet<Type>()
. -
With
globalWatch(variable, tag: object)
, the watched variable will be retrieved by the tag, i.e. retrieve byglobalGet(tag: object)
.
Case 1: By Type
#
//* Step1: Declare the watched variable with `globalWatch`.
final touchCount = globalWatch(0);
lib/pages/locale_page.dart
example/lib/pages/locale_page.dart
class LocalePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
//* Get the watched variable by it's [Type] from `../main.dart`
final mainInt = globalGet<int>();
return Container(
// ...
const SizedBox(height: 25),
//* `globalConsume` the watched variable from `../main.dart`
globalConsume(
() => Text(
'You have pressed the button at the first page ${mainInt.value} times',
),
// ...
Case 2: By tag
#
//* Step1: Declare the watched variable with `globalWatch`.
final touchCount = globalWatch(0, tag: 'tagCount');
lib/pages/locale_page.dart
example/lib/pages/locale_page.dart
class LocalePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
//* Get the watched variable by [tag] from `../main.dart`
final mainInt = globalGet('tagCount');
return Container(
// ...
const SizedBox(height: 25),
//* `globalConsume` the watched variable from `../main.dart`
globalConsume(
() => Text(
'You have pressed the button at the first page ${mainInt.value} times',
),
// ...
Note #
-
Make sure the watched variable is initialized, only after the page is loaded.
-
When using
Type
to retrieve the watched variable, only the first one of theType
is returned.
Or put the watched variables into a file and then import it.
Global Broadcast #
globalBroadcast()
, to broadcast to all the globalConsume widgets.globalConsumeAll(Widget Function() create, {Key? key})
, to create a widget which will be rebuilt whenever any watched variables changes are made.globalFrameAspects
, a getter, to return the updated aspects.globalAllAspects
, a getter, to return all the aspects that has been registered.
Persistence #
defaultVal.globalPersist('key')
#
Create a persistent watched variable. Type of int
, double
, String
, and bool
are supported.
/// int: 0.globalPersist('intKey');
/// double: 0.0.globalPersist('doubleKey');
/// String: ''.globalPersist('StringKey');
/// bool: false.globalPersist('boolKey');
/// ex:
const DefaultLocale = 'en';
final locale = DefaultLocale.globalPersist('locale');
final themeIdx = 1.globalPersist('themeIdx');
await initGlobalPersis()
#
Initial the persistent store in the main()
before runApp()
.
Future<void> main() async {
//* Initial the persistent store.
await initGlobalPersist();
runApp(
//* Create the host with `globalHost` at the top of the widget tree.
globalHost(child: MyApp())
);
}
getPersistStore()
#
Get the backend persistent store, a SharedPreferences
.
final prefs = getPersistStore();`
persistVar.remove()
#
Remove the persistent key/value from the persistent store, and set the value of the persistVar to the default value.
Won't notify the host to rebuild.
persistVar.store(input)
#
Store the input
value to the persistVar.
Won't notify the host to rebuild.
Versions #
- Flutter Mediator: Global Mode + Model Mode.
- Lite: Global Mode only.
- Persistence: Lite + built in persistence.
Example: Logins to a REST server #
A boilerplate example that logins to a REST server with i18n, theming, persistence and state management.
Please see the login to a REST server example for details.
Flutter Widget of the Week: InheritedModel explained #
InheritedModel provides an aspect parameter to its descendants to indicate which fields they care about to determine whether that widget needs to rebuild. InheritedModel can help you rebuild its descendants only when necessary.
Changelog #
Please see the Changelog page.
License #
Flutter Mediator Persistence is distributed under the MIT License. See LICENSE for more information.