From e3931d8b8288ab4ca68b513ffcf98351f429ebfc Mon Sep 17 00:00:00 2001 From: Gogs Date: Mon, 11 Mar 2024 15:49:06 +0100 Subject: [PATCH] flutter_meal final --- lib/models/meal.dart | 2 +- lib/screens/categories.dart | 4 +- lib/screens/filters.dart | 203 ++++++++++++++++------------ lib/screens/tabs.dart | 42 +++++- lib/widgets/category_grid_item.dart | 4 +- lib/widgets/main_drawer.dart | 71 +++------- 6 files changed, 182 insertions(+), 144 deletions(-) diff --git a/lib/models/meal.dart b/lib/models/meal.dart index 6f4ceb0..3d91c6b 100644 --- a/lib/models/meal.dart +++ b/lib/models/meal.dart @@ -40,4 +40,4 @@ class Meal { final bool isLactoseFree; final bool isVegan; final bool isVegetarian; -} \ No newline at end of file +} diff --git a/lib/screens/categories.dart b/lib/screens/categories.dart index 44ec94b..b74eb7b 100644 --- a/lib/screens/categories.dart +++ b/lib/screens/categories.dart @@ -10,12 +10,14 @@ class CategoriesScreen extends StatelessWidget { const CategoriesScreen({ super.key, required this.onToggleFavorites, + required this.availableMeals, }); final void Function(Meal meal) onToggleFavorites; + final List availableMeals; void _selectCategory(BuildContext context, Category category) { - final filteredMeals = dummyMeals + final filteredMeals = availableMeals .where((meal) => meal.categories.contains(category.id)) .toList(); diff --git a/lib/screens/filters.dart b/lib/screens/filters.dart index 9be0048..55f9ee7 100644 --- a/lib/screens/filters.dart +++ b/lib/screens/filters.dart @@ -3,11 +3,21 @@ import 'package:flutter/material.dart'; // import 'package:flutter_navigation/screens/tabs.dart'; // import 'package:flutter_navigation/widgets/main_drawer.dart'; +enum Filter { + glutenFree, + lactoseFree, + vegetarien, + vegan, +} + class FiltersScreen extends StatefulWidget { const FiltersScreen({ super.key, + required this.currentFilters, }); + final Map currentFilters; + @override State createState() { return _FiltersScreenState(); @@ -20,6 +30,16 @@ class _FiltersScreenState extends State { var _vegetarianFilterSet = false; var _veganFilterSet = false; + @override + void initState() { + super.initState(); + + _glutenFilterSet = widget.currentFilters[Filter.glutenFree]!; + _lactoseFilterSet = widget.currentFilters[Filter.lactoseFree]!; + _vegetarianFilterSet = widget.currentFilters[Filter.vegetarien]!; + _veganFilterSet = widget.currentFilters[Filter.vegan]!; + } + @override Widget build(BuildContext context) { return Scaffold( @@ -38,96 +58,107 @@ class _FiltersScreenState extends State { // } // }, // ), - body: Column(children: [ - SwitchListTile( - value: _glutenFilterSet, - onChanged: (isChecked) { - setState(() { - _glutenFilterSet = isChecked; - }); - }, - title: Text( - 'Gluten-free', - style: Theme.of(context).textTheme.titleLarge!.copyWith( - color: Theme.of(context).colorScheme.onBackground, - ), - ), - subtitle: Text( - 'Only include gluten-free meals.', - style: Theme.of(context).textTheme.labelMedium!.copyWith( - color: Theme.of(context).colorScheme.onBackground, - ), - ), - activeColor: Theme.of(context).colorScheme.tertiary, - contentPadding: const EdgeInsets.only(left: 34, right: 22), - ), - SwitchListTile( - value: _lactoseFilterSet, - onChanged: (isChecked) { - setState(() { - _lactoseFilterSet = isChecked; - }); - }, - title: Text( - 'Lactose-free', - style: Theme.of(context).textTheme.titleLarge!.copyWith( - color: Theme.of(context).colorScheme.onBackground, - ), + body: WillPopScope( + onWillPop: () async { + Navigator.of(context).pop({ + Filter.glutenFree: _glutenFilterSet, + Filter.lactoseFree: _lactoseFilterSet, + Filter.vegetarien: _vegetarianFilterSet, + Filter.vegan: _veganFilterSet, + }); + return false; + }, + child: Column(children: [ + SwitchListTile( + value: _glutenFilterSet, + onChanged: (isChecked) { + setState(() { + _glutenFilterSet = isChecked; + }); + }, + title: Text( + 'Gluten-free', + style: Theme.of(context).textTheme.titleLarge!.copyWith( + color: Theme.of(context).colorScheme.onBackground, + ), + ), + subtitle: Text( + 'Only include gluten-free meals.', + style: Theme.of(context).textTheme.labelMedium!.copyWith( + color: Theme.of(context).colorScheme.onBackground, + ), + ), + activeColor: Theme.of(context).colorScheme.tertiary, + contentPadding: const EdgeInsets.only(left: 34, right: 22), ), - subtitle: Text( - 'Only include lactose-free meals.', - style: Theme.of(context).textTheme.labelMedium!.copyWith( - color: Theme.of(context).colorScheme.onBackground, - ), + SwitchListTile( + value: _lactoseFilterSet, + onChanged: (isChecked) { + setState(() { + _lactoseFilterSet = isChecked; + }); + }, + title: Text( + 'Lactose-free', + style: Theme.of(context).textTheme.titleLarge!.copyWith( + color: Theme.of(context).colorScheme.onBackground, + ), + ), + subtitle: Text( + 'Only include lactose-free meals.', + style: Theme.of(context).textTheme.labelMedium!.copyWith( + color: Theme.of(context).colorScheme.onBackground, + ), + ), + activeColor: Theme.of(context).colorScheme.tertiary, + contentPadding: const EdgeInsets.only(left: 34, right: 22), ), - activeColor: Theme.of(context).colorScheme.tertiary, - contentPadding: const EdgeInsets.only(left: 34, right: 22), - ), - SwitchListTile( - value: _vegetarianFilterSet, - onChanged: (isChecked) { - setState(() { - _vegetarianFilterSet = isChecked; - }); - }, - title: Text( - 'Vegetarian', - style: Theme.of(context).textTheme.titleLarge!.copyWith( - color: Theme.of(context).colorScheme.onBackground, - ), + SwitchListTile( + value: _vegetarianFilterSet, + onChanged: (isChecked) { + setState(() { + _vegetarianFilterSet = isChecked; + }); + }, + title: Text( + 'Vegetarian', + style: Theme.of(context).textTheme.titleLarge!.copyWith( + color: Theme.of(context).colorScheme.onBackground, + ), + ), + subtitle: Text( + 'Only include vegetarian meals.', + style: Theme.of(context).textTheme.labelMedium!.copyWith( + color: Theme.of(context).colorScheme.onBackground, + ), + ), + activeColor: Theme.of(context).colorScheme.tertiary, + contentPadding: const EdgeInsets.only(left: 34, right: 22), ), - subtitle: Text( - 'Only include vegetarian meals.', - style: Theme.of(context).textTheme.labelMedium!.copyWith( - color: Theme.of(context).colorScheme.onBackground, - ), + SwitchListTile( + value: _veganFilterSet, + onChanged: (isChecked) { + setState(() { + _veganFilterSet = isChecked; + }); + }, + title: Text( + 'Vegan', + style: Theme.of(context).textTheme.titleLarge!.copyWith( + color: Theme.of(context).colorScheme.onBackground, + ), + ), + subtitle: Text( + 'Only include vegan meals.', + style: Theme.of(context).textTheme.labelMedium!.copyWith( + color: Theme.of(context).colorScheme.onBackground, + ), + ), + activeColor: Theme.of(context).colorScheme.tertiary, + contentPadding: const EdgeInsets.only(left: 34, right: 22), ), - activeColor: Theme.of(context).colorScheme.tertiary, - contentPadding: const EdgeInsets.only(left: 34, right: 22), - ), - SwitchListTile( - value: _veganFilterSet, - onChanged: (isChecked) { - setState(() { - _veganFilterSet = isChecked; - }); - }, - title: Text( - 'Vegan', - style: Theme.of(context).textTheme.titleLarge!.copyWith( - color: Theme.of(context).colorScheme.onBackground, - ), - ), - subtitle: Text( - 'Only include vegan meals.', - style: Theme.of(context).textTheme.labelMedium!.copyWith( - color: Theme.of(context).colorScheme.onBackground, - ), - ), - activeColor: Theme.of(context).colorScheme.tertiary, - contentPadding: const EdgeInsets.only(left: 34, right: 22), - ), - ]), + ]), + ), ); } } diff --git a/lib/screens/tabs.dart b/lib/screens/tabs.dart index fb7f73e..8da2d86 100644 --- a/lib/screens/tabs.dart +++ b/lib/screens/tabs.dart @@ -1,4 +1,5 @@ import 'package:flutter/material.dart'; +import 'package:flutter_navigation/data/dummy_data.dart'; import 'package:flutter_navigation/screens/categories.dart'; import 'package:flutter_navigation/screens/meals.dart'; import 'package:flutter_navigation/widgets/main_drawer.dart'; @@ -6,6 +7,13 @@ import 'package:flutter_navigation/widgets/main_drawer.dart'; import '../models/meal.dart'; import 'filters.dart'; +const kInitialFilters = { + Filter.glutenFree: false, + Filter.lactoseFree: false, + Filter.vegetarien: false, + Filter.vegan: false, +}; + class TabsScreen extends StatefulWidget { const TabsScreen({super.key}); @@ -18,6 +26,7 @@ class TabsScreen extends StatefulWidget { class _TabsScreenState extends State { int _selectedPageIndex = 0; final List _favoriteMeals = []; + Map _selectedFilters = kInitialFilters; void _showInfoMessage(String message) { ScaffoldMessenger.of(context).clearSnackBars(); @@ -46,21 +55,48 @@ class _TabsScreenState extends State { }); } - void _setScreen(String identifier) { + void _setScreen(String identifier) async { Navigator.of(context).pop(); if (identifier == 'filters') { - Navigator.of(context).push( + final result = await Navigator.of(context).push>( MaterialPageRoute( - builder: (ctx) => const FiltersScreen(), + builder: (ctx) => FiltersScreen( + currentFilters: _selectedFilters, + ), ), ); + + setState(() { + _selectedFilters = result ?? kInitialFilters; + }); } } @override Widget build(BuildContext context) { + final availableMeals = dummyMeals.where((meal) { + if (_selectedFilters[Filter.glutenFree]! && !meal.isGlutenFree) { + return false; + } + + if (_selectedFilters[Filter.lactoseFree]! && !meal.isLactoseFree) { + return false; + } + + if (_selectedFilters[Filter.vegetarien]! && !meal.isVegetarian) { + return false; + } + + if (_selectedFilters[Filter.vegan]! && !meal.isVegan) { + return false; + } + + return true; + }).toList(); + Widget activePage = CategoriesScreen( onToggleFavorites: _toggleMealFavoriteStatus, + availableMeals: availableMeals, ); var activePageTitle = 'Categories'; diff --git a/lib/widgets/category_grid_item.dart b/lib/widgets/category_grid_item.dart index 879dc60..dcac7e1 100644 --- a/lib/widgets/category_grid_item.dart +++ b/lib/widgets/category_grid_item.dart @@ -34,8 +34,8 @@ class CategoryGridItem extends StatelessWidget { child: Text( category.title, style: Theme.of(context).textTheme.titleLarge!.copyWith( - color: Theme.of(context).colorScheme.onBackground, - ), + color: Theme.of(context).colorScheme.onBackground, + ), ), ), ); diff --git a/lib/widgets/main_drawer.dart b/lib/widgets/main_drawer.dart index 293f456..e775873 100644 --- a/lib/widgets/main_drawer.dart +++ b/lib/widgets/main_drawer.dart @@ -1,7 +1,10 @@ import 'package:flutter/material.dart'; class MainDrawer extends StatelessWidget { - const MainDrawer({ super.key, required this .onSelectScreen,}); + const MainDrawer({ + super.key, + required this.onSelectScreen, + }); final void Function(String identifier) onSelectScreen; @@ -15,12 +18,8 @@ class MainDrawer extends StatelessWidget { decoration: BoxDecoration( gradient: LinearGradient( colors: [ - Theme - .of(context) - .colorScheme - .primaryContainer, - Theme - .of(context) + Theme.of(context).colorScheme.primaryContainer, + Theme.of(context) .colorScheme .primaryContainer .withOpacity(0.8), @@ -34,24 +33,14 @@ class MainDrawer extends StatelessWidget { Icon( Icons.fastfood, size: 48, - color: Theme - .of(context) - .colorScheme - .primary, + color: Theme.of(context).colorScheme.primary, ), const SizedBox(width: 18), Text( 'Cooking Up!', - style: Theme - .of(context) - .textTheme - .titleLarge! - .copyWith( - color: Theme - .of(context) - .colorScheme - .primary, - ), + style: Theme.of(context).textTheme.titleLarge!.copyWith( + color: Theme.of(context).colorScheme.primary, + ), ) ], ), @@ -60,24 +49,14 @@ class MainDrawer extends StatelessWidget { leading: Icon( Icons.restaurant, size: 26, - color: Theme - .of(context) - .colorScheme - .onBackground, + color: Theme.of(context).colorScheme.onBackground, ), title: Text( 'Meals', - style: Theme - .of(context) - .textTheme - .titleSmall! - .copyWith( - color: Theme - .of(context) - .colorScheme - .onBackground, - fontSize: 24, - ), + style: Theme.of(context).textTheme.titleSmall!.copyWith( + color: Theme.of(context).colorScheme.onBackground, + fontSize: 24, + ), ), onTap: () { onSelectScreen('meals'); @@ -87,24 +66,14 @@ class MainDrawer extends StatelessWidget { leading: Icon( Icons.settings, size: 26, - color: Theme - .of(context) - .colorScheme - .onBackground, + color: Theme.of(context).colorScheme.onBackground, ), title: Text( 'Filters', - style: Theme - .of(context) - .textTheme - .titleSmall! - .copyWith( - color: Theme - .of(context) - .colorScheme - .onBackground, - fontSize: 24, - ), + style: Theme.of(context).textTheme.titleSmall!.copyWith( + color: Theme.of(context).colorScheme.onBackground, + fontSize: 24, + ), ), onTap: () { onSelectScreen('filters');