Reputation: 11
I made an Expense Tracker app which has a List named '_registeredExpenses'. This list stores all the expenses to be displayed when the app is opened . Now my problem is that when i kill the app , it doesnot store the added values or the deleted values . It just reverts back to its original state (original state has two hardcoded rows i.e handwash and cinema).
i tried to implement state restoration by extending the class RestorationMixin and then following the approach given in this video :https://youtu.be/5-u5VjPJsNI
Now my problem is that i wanted to convert the List named '_registeredExpenses' to a type of Restorable property so that it could be recieved as property argument by the registerForRestoration method (as is the approach given in the youtube video) , But so far all i get is error.enter image description here
it is saying this :
The argument type 'List<Expense>' can't be assigned to the parameter type 'RestorableProperty<Object?>'.dart argument_type_not_assignable
below are two images from my app: First pic shows the state after adding an expense titled 'Milk' and before kiling the app.
Second pic shows the state after kiling the app and restarting it.
I got the app to run by commenting out the error area( So that i could show what i am talking about ).
below is my code snippet where I implemented the RestorationMixin :
import 'package:expense_tracker/main.dart';
import 'package:expense_tracker/widgets/chart/chart.dart';
import 'package:expense_tracker/widgets/new_expense.dart';
import 'package:flutter/material.dart';
import 'package:expense_tracker/models/expense.dart';
import 'package:expense_tracker/widgets/expenses_list/expenses_list.dart';
class Expenses extends StatefulWidget {
const Expenses({super.key});
@override
State<Expenses> createState() {
return _ExpensesState();
}
}
class _ExpensesState extends State<Expenses> with RestorationMixin {
final List<Expense> _registeredExpenses = [
Expense(
title: 'Handwash',
amount: 19.99,
date: DateTime.now(),
category: Category.hygiene,
),
Expense(
title: 'Cinema',
amount: 150.69,
date: DateTime.now(),
category: Category.leisure,
),
];
void _openAddExpenseOverlay() {
showModalBottomSheet(
isScrollControlled:
true, //this ensures that the overlay takes full space available
context: context,
builder: (ctx) {
return NewExpense(onAddExpense: _addExpense);
});
}
void _addExpense(Expense expense) {
setState(() {
_registeredExpenses.add(expense);
});
}
void _removeExpense(Expense expense) {
final expenseIndex = _registeredExpenses.indexOf(expense);
setState(() {
_registeredExpenses.remove(expense);
});
ScaffoldMessenger.of(context)
.clearSnackBars(); //clears any info message of prior deletions
ScaffoldMessenger.of(context).showSnackBar(SnackBar(
duration: const Duration(seconds: 4),
content: const Text("Expense deleted"),
action: SnackBarAction(
textColor: Colors.lightBlue,
label: "Undo",
onPressed: () {
setState(() {
// if undo pressed , insert the expense back
_registeredExpenses.insert(expenseIndex, expense);
});
},
),
));
}
@override
Widget build(BuildContext context) {
Widget mainContent = const Center(
child: Text("No expenses found. Kindly start adding. "),
);
if (_registeredExpenses.isNotEmpty) {
mainContent = ExpensesList(
expenses: _registeredExpenses,
onRemoveExpense: _removeExpense,
);
}
return Scaffold(
appBar: AppBar(
//backgroundColor: Colors.blueGrey,
title: const Text("e-KHATA"),
actions: [
IconButton(
onPressed: _openAddExpenseOverlay,
icon: const Icon(
Icons.add_rounded,
//color: Colors.deepOrange,
))
],
),
body: Column(
children: [
Chart(expenses: _registeredExpenses),
Expanded(child: mainContent)
],
),
);
}
@override
String? get restorationId => "RegdExpensesList";
@override
void restoreState(RestorationBucket? oldBucket, bool initialRestore) {
registerForRestoration(_registeredExpenses, "RegD_Expenses");
}
}
The error is Coming in the registerForRestoration method inside the restoreState method .
Please guide me . I am new to flutter . I have tried a lot but i don't know what to do.
Upvotes: 1
Views: 911
Reputation: 344
You need to make a custom restorable for your data type: Checkout this code example https://api.flutter.dev/flutter/widgets/RestorableValue-class.html
Although I would reccomend keeping the state persisted somewhere else. Checkout Riverpod and it's StateProvider for an extremely easy solution.
Upvotes: 0