provider_persist
provider_persist copied to clipboard
Persist your UI State with Provider.
provider_persist
A Flutter Template to show how to persist provider.
Getting Started
Example of how to persist UI state with Provider.
UI
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import '../../data/classes/index.dart';
import '../../data/models/index.dart';
import '../index.dart';
class TasksScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Flutter Task Manager'),
),
body: Consumer<TaskProvider>(
builder: (context, model, child) {
if (model?.tasks == null) {
return Center(
child: CircularProgressIndicator(),
);
}
if (model.tasks.isEmpty) {
return Center(
child: Text('No Tasks Found'),
);
}
return ListView.separated(
separatorBuilder: (context, index) => Divider(),
itemCount: model.tasks.length,
itemBuilder: (context, index) {
final _item = model.tasks[index];
return ListTile(
title: Text(_item.name),
trailing: IconButton(
icon: Icon(Icons.delete),
onPressed: () => model.deleteTask(index),
),
onTap: () => _editTask(context, _item, index),
);
},
);
},
),
floatingActionButton: FloatingActionButton(
child: Icon(Icons.add),
onPressed: () => _addTask(context),
),
);
}
void _addTask(BuildContext context) async {
final _task = await Navigator.push<Task>(
context,
MaterialPageRoute(
builder: (_) => EditTaskScreen(),
fullscreenDialog: true,
));
if (_task != null) {
final _model = Provider.of<TaskProvider>(context);
_model.addTask(_task);
}
}
void _editTask(BuildContext context, Task task, int index) async {
final _task = await Navigator.push<Task>(
context,
MaterialPageRoute(
builder: (_) => EditTaskScreen(task: task),
fullscreenDialog: false,
));
if (_task != null) {
final _model = Provider.of<TaskProvider>(context);
_model.editTask(index, _task);
}
}
}
Model
import 'package:flutter/cupertino.dart';
import 'package:json_annotation/json_annotation.dart';
import 'package:localstorage/localstorage.dart';
import '../classes/index.dart';
part 'task_state.g.dart';
class TaskProvider extends ChangeNotifier {
TaskState _state;
final String _stateKey = 'state';
final _storage = LocalStorage('Task-state');
void init() async {
await _storage.ready;
final _data = _storage.getItem(_stateKey);
try {
if (_data != null) {
_state = TaskState.fromJson(_data);
}
} catch (e) {
print('Error Loading Task State: $e');
}
if (_data == null) {
_state = TaskState(tasks: []);
}
notifyListeners();
}
List<Task> get tasks => _state?.tasks;
void addTask(Task value) {
_state.tasks.add(value);
notifyListeners();
_saveState();
}
void editTask(int index, Task value) {
_state.tasks[index] = value;
notifyListeners();
_saveState();
}
void deleteTask(int index) {
_state.tasks.removeAt(index);
notifyListeners();
_saveState();
}
void _saveState() async => await _storage.setItem(_stateKey, _state.toJson());
}
@JsonSerializable(nullable: false, explicitToJson: true)
class TaskState {
TaskState({this.tasks});
factory TaskState.fromJson(Map<String, dynamic> json) =>
_$TaskStateFromJson(json);
List<Task> tasks;
Map<String, dynamic> toJson() => _$TaskStateToJson(this);
}
Class
To update run: flutter packages pub run build_runner watch —delete-conflicting-outputs
import 'package:flutter/foundation.dart';
import 'package:json_annotation/json_annotation.dart';
part 'task.g.dart';
@JsonSerializable(nullable: false)
class Task {
final String name;
final bool active;
final DateTime dataCreated;
Task({
@required this.name,
@required this.dataCreated,
this.active: true,
});
factory Task.fromJson(Map<String, dynamic> json) => _$TaskFromJson(json);
Map<String, dynamic> toJson() => _$TaskToJson(this);
}