Skip to content

Commit

Permalink
Make Veggie Seasons restorable
Browse files Browse the repository at this point in the history
  • Loading branch information
goderbauer committed Oct 12, 2020
1 parent 5ea190e commit f8872fb
Show file tree
Hide file tree
Showing 11 changed files with 433 additions and 234 deletions.
66 changes: 60 additions & 6 deletions veggieseasons/lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -17,19 +17,73 @@ void main() {
]);

runApp(
MultiProvider(
RootRestorationScope(
restorationId: 'root',
child: VeggieApp(),
),
);
}

class VeggieApp extends StatefulWidget {
@override
State<StatefulWidget> createState() => _VeggieAppState();
}

class _VeggieAppState extends State<VeggieApp> with RestorationMixin {
final _RestorableAppState _appState = _RestorableAppState();

@override
String get restorationId => 'wrapper';

@override
void restoreState(RestorationBucket oldBucket, bool initialRestore) {
registerForRestoration(_appState, 'state');
}

@override
void dispose() {
super.dispose();
_appState.dispose();
}

@override
Widget build(BuildContext context) {
return MultiProvider(
providers: [
ChangeNotifierProvider(
create: (_) => AppState(),
ChangeNotifierProvider.value(
value: _appState.value,
),
ChangeNotifierProvider(
create: (_) => Preferences()..load(),
),
],
child: CupertinoApp(
debugShowCheckedModeBanner: false,
home: HomeScreen(),
home: HomeScreen(restorationId: 'home'),
restorationScopeId: 'app',
),
),
);
);
}
}

class _RestorableAppState extends RestorableListenable<AppState> {
@override
AppState createDefaultValue() {
return AppState();
}

@override
AppState fromPrimitives(Object data) {
final appState = AppState();
final favorites = (data as List<dynamic>).cast<int>();
for (var id in favorites) {
appState.setFavorite(id, true);
}
return appState;
}

@override
Object toPrimitives() {
return value.favoriteVeggies.map((veggie) => veggie.id).toList();
}
}
89 changes: 60 additions & 29 deletions veggieseasons/lib/screens/details.dart
Original file line number Diff line number Diff line change
Expand Up @@ -238,15 +238,42 @@ class InfoView extends StatelessWidget {

class DetailsScreen extends StatefulWidget {
final int id;
final String restorationId;

DetailsScreen(this.id);
DetailsScreen({this.id, this.restorationId});

static String show(NavigatorState navigator, int veggieId) {
return navigator.restorablePush<void>(_routeBuilder, arguments: veggieId);
}

static Route<void> _routeBuilder(BuildContext context, Object arguments) {
final veggieId = arguments as int;
return CupertinoPageRoute(
builder: (context) => DetailsScreen(id: veggieId, restorationId: 'details'),
fullscreenDialog: true,
);
}

@override
_DetailsScreenState createState() => _DetailsScreenState();
}

class _DetailsScreenState extends State<DetailsScreen> {
int _selectedViewIndex = 0;
class _DetailsScreenState extends State<DetailsScreen> with RestorationMixin {
final RestorableInt _selectedViewIndex = RestorableInt(0);

@override
String get restorationId => widget.restorationId;

@override
void restoreState(RestorationBucket oldBucket, bool initialRestore) {
registerForRestoration(_selectedViewIndex, 'tab');
}

@override
void dispose() {
super.dispose();
_selectedViewIndex.dispose();
}

Widget _buildHeader(BuildContext context, AppState model) {
final veggie = model.getVeggie(widget.id);
Expand Down Expand Up @@ -282,33 +309,37 @@ class _DetailsScreenState extends State<DetailsScreen> {
Widget build(BuildContext context) {
final appState = Provider.of<AppState>(context);

return CupertinoPageScaffold(
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
mainAxisSize: MainAxisSize.min,
children: [
Expanded(
child: ListView(
children: [
_buildHeader(context, appState),
SizedBox(height: 20),
CupertinoSegmentedControl<int>(
children: {
0: Text('Facts & Info'),
1: Text('Trivia'),
},
groupValue: _selectedViewIndex,
onValueChanged: (value) {
setState(() => _selectedViewIndex = value);
},
),
_selectedViewIndex == 0
? InfoView(widget.id)
: TriviaView(widget.id),
],
return UnmanagedRestorationScope(
bucket: bucket,
child: CupertinoPageScaffold(
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
mainAxisSize: MainAxisSize.min,
children: [
Expanded(
child: ListView(
restorationId: 'list',
children: [
_buildHeader(context, appState),
SizedBox(height: 20),
CupertinoSegmentedControl<int>(
children: {
0: Text('Facts & Info'),
1: Text('Trivia'),
},
groupValue: _selectedViewIndex.value,
onValueChanged: (value) {
setState(() => _selectedViewIndex.value = value);
},
),
_selectedViewIndex.value == 0
? InfoView(widget.id)
: TriviaView(id: widget.id, restorationId: 'trivia'),
],
),
),
),
],
],
),
),
);
}
Expand Down
6 changes: 6 additions & 0 deletions veggieseasons/lib/screens/favorites.dart
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,14 @@ import 'package:veggieseasons/styles.dart';
import 'package:veggieseasons/widgets/veggie_headline.dart';

class FavoritesScreen extends StatelessWidget {
FavoritesScreen({this.restorationId, Key key}) : super(key: key);

final String restorationId;

@override
Widget build(BuildContext context) {
return CupertinoTabView(
restorationScopeId: restorationId,
builder: (context) {
final model = Provider.of<AppState>(context);

Expand All @@ -32,6 +37,7 @@ class FavoritesScreen extends StatelessWidget {
),
)
: ListView(
restorationId: 'list',
children: [
SizedBox(height: 24),
for (Veggie veggie in model.favoriteVeggies)
Expand Down
68 changes: 38 additions & 30 deletions veggieseasons/lib/screens/home.dart
Original file line number Diff line number Diff line change
Expand Up @@ -10,38 +10,46 @@ import 'package:veggieseasons/screens/search.dart';
import 'package:veggieseasons/screens/settings.dart';

class HomeScreen extends StatelessWidget {
HomeScreen({Key key, this.restorationId}) : super(key: key);

final String restorationId;

@override
Widget build(BuildContext context) {
return CupertinoTabScaffold(
tabBar: CupertinoTabBar(items: [
BottomNavigationBarItem(
icon: Icon(CupertinoIcons.home),
label: 'Home',
),
BottomNavigationBarItem(
icon: Icon(CupertinoIcons.book),
label: 'My Garden',
),
BottomNavigationBarItem(
icon: Icon(CupertinoIcons.search),
label: 'Search',
),
BottomNavigationBarItem(
icon: Icon(CupertinoIcons.settings),
label: 'Settings',
),
]),
tabBuilder: (context, index) {
if (index == 0) {
return ListScreen();
} else if (index == 1) {
return FavoritesScreen();
} else if (index == 2) {
return SearchScreen();
} else {
return SettingsScreen();
}
},
return RestorationScope(
restorationId: restorationId,
child: CupertinoTabScaffold(
restorationId: 'scaffold',
tabBar: CupertinoTabBar(items: [
BottomNavigationBarItem(
icon: Icon(CupertinoIcons.home),
label: 'Home',
),
BottomNavigationBarItem(
icon: Icon(CupertinoIcons.book),
label: 'My Garden',
),
BottomNavigationBarItem(
icon: Icon(CupertinoIcons.search),
label: 'Search',
),
BottomNavigationBarItem(
icon: Icon(CupertinoIcons.settings),
label: 'Settings',
),
]),
tabBuilder: (context, index) {
if (index == 0) {
return ListScreen(restorationId: 'list');
} else if (index == 1) {
return FavoritesScreen(restorationId: 'favorites');
} else if (index == 2) {
return SearchScreen(restorationId: 'search');
} else {
return SettingsScreen(restorationId: 'settings');
}
},
),
);
}
}
6 changes: 6 additions & 0 deletions veggieseasons/lib/screens/list.dart
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@ import 'package:veggieseasons/styles.dart';
import 'package:veggieseasons/widgets/veggie_card.dart';

class ListScreen extends StatelessWidget {
ListScreen({this.restorationId, Key key}) : super(key: key);

final String restorationId;

Widget _generateVeggieRow(Veggie veggie, Preferences prefs,
{bool inSeason = true}) {
return Padding(
Expand All @@ -29,6 +33,7 @@ class ListScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
return CupertinoTabView(
restorationScopeId: restorationId,
builder: (context) {
var dateString = DateFormat('MMMM y').format(DateTime.now());

Expand All @@ -38,6 +43,7 @@ class ListScreen extends StatelessWidget {
return SafeArea(
bottom: false,
child: ListView.builder(
restorationId: 'list',
itemCount: appState.allVeggies.length + 2,
itemBuilder: (context, index) {
if (index == 0) {
Expand Down
Loading

0 comments on commit f8872fb

Please sign in to comment.