Post Detail

Post #103

Flutter Jour Cinq Part 3

Flutter Jour Cinq (Part 3) Part 2

DeliMeals

  • 15:00 - 15:45 : Ajout des Filters

Code

 1import 'package:delimeals/dummy_data.dart';
 2import 'package:delimeals/models/meal.dart';
 3import 'package:delimeals/screens/category_meals_screen.dart';
 4import 'package:delimeals/screens/meal_detail_screen.dart';
 5import 'package:delimeals/screens/tabs_screen.dart';
 6import 'package:delimeals/widgets/filters_screen.dart';
 7import 'package:flutter/material.dart';
 8
 9void main() {
10  runApp(MyApp());
11}
12
13class MyApp extends StatefulWidget {
14  @override
15  _MyAppState createState() => _MyAppState();
16}
17
18class _MyAppState extends State<MyApp> {
19  Map<String, bool> _filters = {
20    'gluten': false,
21    'lactose': false,
22    'vegan': false,
23    'vegetarian': false,
24  };
25
26  List<Meal> _availableMeals = DUMMY_MEALS;
27
28  void _setFilters(Map<String, bool> filterData) {
29    setState(() {
30      _filters = filterData;
31
32      _availableMeals = DUMMY_MEALS.where((meal) {
33        if (_filters['gluten'] && !meal.isGlutenFree) {
34          return false;
35        }
36        if (_filters['lactose'] && !meal.isLactoseFree) {
37          return false;
38        }
39        if (_filters['vegan'] && !meal.isVegan) {
40          return false;
41        }
42        if (_filters['vegetarian'] && !meal.isVegetarian) {
43          return false;
44        }
45        return true;
46      }).toList();
47    });
48  }
49
50  @override
51  Widget build(BuildContext context) {
52    return MaterialApp(
53      title: 'DeliMeals',
54      theme: ThemeData(
55        primarySwatch: Colors.pink,
56        accentColor: Colors.amber,
57        canvasColor: Color.fromRGBO(255, 254, 229, 1),
58        fontFamily: 'Raleway',
59        textTheme: TextTheme(
60          headline6: TextStyle(
61            fontWeight: FontWeight.bold,
62          ),
63        ),
64      ),
65      routes: {
66        '/': (context) => TabsScreen(),
67        CategoryMealsScreen.routeName: (context) =>
68            CategoryMealsScreen(_availableMeals),
69        MealDetailScreen.routeName: (context) => MealDetailScreen(),
70        FiltersScreen.routeName: (context) =>
71            FiltersScreen(_filters, _setFilters),
72      },
73    );
74  }
75}
76
77class MyHomePage extends StatefulWidget {
78  @override
79  _MyHomePageState createState() => _MyHomePageState();
80}
81
82class _MyHomePageState extends State<MyHomePage> {
83  @override
84  Widget build(BuildContext context) {
85    return Scaffold(
86      appBar: AppBar(
87        title: Text('DeliMeals'),
88      ),
89      body: Center(
90        child: Text('Navigation Time!'),
91      ),
92    );
93  }
94}
  1import 'package:delimeals/widgets/main_drawer.dart';
  2import 'package:flutter/material.dart';
  3
  4class FiltersScreen extends StatefulWidget {
  5  static const routeName = '/filters';
  6
  7  final Map<String, bool> currentFilters;
  8  final Function saveFilters;
  9  FiltersScreen(this.currentFilters, this.saveFilters);
 10
 11  @override
 12  _FiltersScreenState createState() => _FiltersScreenState();
 13}
 14
 15class _FiltersScreenState extends State<FiltersScreen> {
 16  var _glutenFree = false;
 17  var _vegetarian = false;
 18  var _vegan = false;
 19  var _lactoseFree = false;
 20
 21  @override
 22  initState() {
 23    _glutenFree = widget.currentFilters['gluten'];
 24    _lactoseFree = widget.currentFilters['lactose'];
 25    _vegan = widget.currentFilters['vegan'];
 26    _vegetarian = widget.currentFilters['vegetarian'];
 27    super.initState();
 28  }
 29
 30  Widget _buildSwitchListTile(String title, String description,
 31      bool currentValue, Function updateValue) {
 32    return SwitchListTile(
 33      title: Text(title),
 34      value: currentValue,
 35      subtitle: Text(
 36        description,
 37      ),
 38      onChanged: updateValue,
 39    );
 40  }
 41
 42  @override
 43  Widget build(BuildContext context) {
 44    return Scaffold(
 45      drawer: MainDrawer(),
 46      appBar: AppBar(
 47        title: Text('Your Filters'),
 48        actions: <Widget>[
 49          IconButton(
 50            icon: Icon(Icons.save),
 51            onPressed: () {
 52              final selectedFilters = {
 53                'gluten': _glutenFree,
 54                'lactose': _lactoseFree,
 55                'vegan': _vegan,
 56                'vegetarian': _vegetarian,
 57              };
 58              widget.saveFilters(selectedFilters);
 59            },
 60          ),
 61        ],
 62      ),
 63      body: Column(
 64        children: [
 65          Container(
 66            padding: EdgeInsets.all(20),
 67            child: Text(
 68              'Adjust your meal selection.',
 69              style: Theme.of(context).textTheme.headline6,
 70            ),
 71          ),
 72          Expanded(
 73            child: ListView(
 74              children: <Widget>[
 75                _buildSwitchListTile(
 76                  'Gluten-free',
 77                  'Only include gluten-free meals',
 78                  _glutenFree,
 79                  (newValue) {
 80                    setState(() {
 81                      _glutenFree = newValue;
 82                    });
 83                  },
 84                ),
 85                _buildSwitchListTile(
 86                  'Lactose-free',
 87                  'Only include lactose-free meals',
 88                  _lactoseFree,
 89                  (newValue) {
 90                    setState(() {
 91                      _lactoseFree = newValue;
 92                    });
 93                  },
 94                ),
 95                _buildSwitchListTile(
 96                  'Vegan',
 97                  'Only include vegan meals',
 98                  _vegan,
 99                  (newValue) {
100                    setState(() {
101                      _vegan = newValue;
102                    });
103                  },
104                ),
105                _buildSwitchListTile(
106                  'Vegetarian',
107                  'Only include vegetarian meals',
108                  _vegetarian,
109                  (newValue) {
110                    setState(() {
111                      _vegetarian = newValue;
112                    });
113                  },
114                ),
115              ],
116            ),
117          ),
118        ],
119      ),
120    );
121  }
122}
 1import 'package:delimeals/dummy_data.dart';
 2import 'package:delimeals/models/meal.dart';
 3import 'package:delimeals/widgets/meal_item.dart';
 4import 'package:flutter/material.dart';
 5
 6class CategoryMealsScreen extends StatefulWidget {
 7  static const routeName = '/category-meals';
 8
 9  final List<Meal> availableMeals;
10  CategoryMealsScreen(this.availableMeals);
11
12  @override
13  _CategoryMealsScreenState createState() => _CategoryMealsScreenState();
14}
15
16class _CategoryMealsScreenState extends State<CategoryMealsScreen> {
17  String categoryTitle;
18  List<Meal> displayedMeals;
19  var _loadedInitData = false;
20
21  @override
22  void initState() {
23    super.initState();
24  }
25
26  @override
27  void didChangeDependencies() {
28    if (!_loadedInitData) {
29      final routeArgs =
30          ModalRoute.of(context).settings.arguments as Map<String, String>;
31      final categoryId = routeArgs['id'];
32
33      categoryTitle = routeArgs['title'];
34      displayedMeals = widget.availableMeals.where((meal) {
35        return meal.categories.contains(categoryId);
36      }).toList();
37
38      _loadedInitData = true;
39    }
40
41    super.didChangeDependencies();
42  }
43
44  void _removeMeal(String mealId) {
45    setState(() {
46      displayedMeals.removeWhere((meal) => meal.id == mealId);
47    });
48  }
49
50  @override
51  Widget build(BuildContext context) {
52    return Scaffold(
53      appBar: AppBar(
54        title: Text(
55          categoryTitle,
56        ),
57      ),
58      body: ListView.builder(
59        itemBuilder: (context, index) {
60          return MealItem(
61            id: displayedMeals[index].id,
62            title: displayedMeals[index].title,
63            imageUrl: displayedMeals[index].imageUrl,
64            duration: displayedMeals[index].duration,
65            complexity: displayedMeals[index].complexity,
66            affordability: displayedMeals[index].affordability,
67            removeItem: _removeMeal,
68          );
69        },
70        itemCount: displayedMeals.length,
71      ),
72    );
73  }
74}