-
Notifications
You must be signed in to change notification settings - Fork 1.5k
[State Restoration] Restorable Material Code Samples - Part 2/3 #379
Conversation
lib/demos/material/menu_demo.dart
Outdated
final void Function(String value) showInSnackBar; | ||
|
||
@override | ||
_ChecklistMenuDemoState createState() => _ChecklistMenuDemoState(); | ||
} | ||
|
||
class _ChecklistMenuDemoState extends State<_ChecklistMenuDemo> { | ||
List<CheckedValue> _checkedValues; | ||
class _RestorableCheckedValue extends RestorableValue<Set<int>> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wondering what you think about this @goderbauer and if you have any suggestions for improving this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My suggestion would be to extend RestorableProperty directly and write a class that looks something like this:
class _RestorableCheckedValues extends RestorableProperty<List<int>> {
Set<CheckedValue> _checked = Set<>();
void check(CheckedValue value) {
_checked.add(value);
notifyListeners();
}
void uncheck(CheckedValue value) {
_checked.remove(value);
notifyListeners();
}
void isChecked(CheckedValue value) {
return _checked.contains(value);
}
void initWithValue(Set<CheckedValue> a) {
_checked = a;
}
@override
Object toPrimitives() {
return _checked.map((a) => e.index).toList();
}
@override
Set<int> fromPrimitives(Object data) {
final checkedValues = data as List<dynamic>;
return Set.from(checkedValues.map<int>((dynamic id) => CheckedValues.values[id as int]));
}
}
(this code probably doesn't compile, but you get the idea)
That way, you get a nice API to use within _ChecklistMenuDemoState.
Looking at the code below, instead of check/uncheck you could also have a simple toggle method. And you probably need to exposes a map function which it takes a callback and iterates over the values in _checked.
@@ -36,13 +51,23 @@ class _DataTableDemoState extends State<DataTableDemo> { | |||
) { | |||
_dessertsDataSource._sort<T>(getField, ascending); | |||
setState(() { | |||
_sortColumnIndex = columnIndex; | |||
_sortAscending = ascending; | |||
// [RestorableBool]'s value cannot be null, so -1 is used as a placeholder |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@goderbauer This is also an interesting problem, since RestorableBool
does not take a null value, but some Flutter widgets use null
to represent something meaningful. I was "lucky" here that the index values could only by greater than or equal to 0, so I used -1
as a substitute for null
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can add an RestorableBoolN
to the framework (and RestorableIntN, etc.) where the N stands for "this property is nullable". Ian and I discussed that as an option before. Feel free to open a PR on framework for that, if you need it.
lib/demos/material/button_demo.dart
Outdated
@override | ||
_ToggleButtonsDemoState createState() => _ToggleButtonsDemoState(); | ||
} | ||
|
||
class _ToggleButtonsDemoState extends State<_ToggleButtonsDemo> { | ||
final isSelected = <bool>[false, false, false]; | ||
class _RestorableBoolList extends RestorableValue<List<bool>> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This only works if a new list is assigned to the property every time.
As an alternative, could _ToggleButtonsDemoState just have a List with three instances of RestorableBool in it? That may be simpler...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM but I think the restoration ID doesn't really need to be a constructor param on these demos and could be a const instead.
lib/demos/material/cards_demo.dart
Outdated
this.restorationId, | ||
}); | ||
|
||
final String restorationId; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does the restorationId need to be a parameter to the constructor? Could it just be a const for each demo instead?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If each demo is only ever used once, that would work just fine and could simplify things.
Description
More State Restoration Demos:
Todos
Bottom Sheet needs work in the Scaffold (filed flutter/flutter#70915)
Dialogs need to support restorablePush (filed flutter/flutter#70918)