1
1
import 'package:flutter/material.dart' ;
2
2
import 'package:food_recipe/src/blocs/searchmeals/search_meals_bloc.dart' ;
3
+ import 'package:food_recipe/src/database/entity/favorite_meal.dart' ;
4
+ import 'package:food_recipe/src/models/lookupmealsbyid/lookup_meals_by_id.dart' ;
3
5
import 'package:food_recipe/src/models/searchmeals/search_meals.dart' ;
4
6
import 'package:food_recipe/src/ui/detailmeals/detail_meals_screen.dart' ;
5
7
import 'package:food_recipe/src/utils/utils.dart' ;
@@ -11,7 +13,6 @@ class SearchMealsScreen extends StatefulWidget {
11
13
}
12
14
13
15
class _SearchMealsScreenState extends State <SearchMealsScreen > {
14
-
15
16
@override
16
17
void dispose () {
17
18
searchMealsBloc.dispose ();
@@ -68,102 +69,16 @@ class _SearchMealsScreenState extends State<SearchMealsScreen> {
68
69
SearchMeals searchMeals = snapshot.data;
69
70
if (searchMeals.isLoading) {
70
71
return Center (child: buildCircularProgressIndicator ());
71
- } else if (searchMeals.searchMealsItems == null || searchMeals.searchMealsItems.isEmpty) {
72
+ } else if (searchMeals.searchMealsItems == null ||
73
+ searchMeals.searchMealsItems.isEmpty) {
72
74
return Container ();
73
75
}
74
76
return ListView .builder (
75
77
shrinkWrap: true ,
76
78
itemCount: searchMeals.searchMealsItems.length,
77
79
itemBuilder: (context, index) {
78
80
var searchMealsItem = searchMeals.searchMealsItems[index];
79
- return Padding (
80
- padding: EdgeInsets .only (bottom: 16.0 ),
81
- child: GestureDetector (
82
- onTap: () {
83
- Navigator .push (
84
- context,
85
- MaterialPageRoute (
86
- builder: (context) {
87
- return DetailMealsScreen (
88
- searchMealsItem.idMeal,
89
- searchMealsItem.strMeal,
90
- searchMealsItem.strMealThumb,
91
- );
92
- },
93
- ),
94
- );
95
- },
96
- child: Card (
97
- elevation: 8.0 ,
98
- shape: RoundedRectangleBorder (
99
- borderRadius: BorderRadius .circular (16.0 ),
100
- ),
101
- child: ClipRRect (
102
- borderRadius: BorderRadius .circular (16.0 ),
103
- child: Stack (
104
- children: < Widget > [
105
- Hero (
106
- tag: "image_detail_meals_${searchMealsItem .idMeal }" ,
107
- child: FadeInImage (
108
- image: NetworkImage (searchMealsItem.strMealThumb),
109
- placeholder: AssetImage (
110
- "assets/images/img_placeholder.jpg" ),
111
- fit: BoxFit .cover,
112
- width: double .infinity,
113
- height: mediaQuery.size.width / 1.5 ,
114
- ),
115
- ),
116
- Container (
117
- width: double .infinity,
118
- height: mediaQuery.size.width / 1.5 ,
119
- decoration: BoxDecoration (
120
- gradient: LinearGradient (
121
- begin: Alignment .topCenter,
122
- end: Alignment .bottomCenter,
123
- stops: [
124
- 0.1 ,
125
- 0.9
126
- ],
127
- colors: [
128
- Color (0xFFFFFFFF ),
129
- Color (0x00FFFFFF ),
130
- ]),
131
- ),
132
- ),
133
- Padding (
134
- padding: EdgeInsets .all (16.0 ),
135
- child: Row (
136
- crossAxisAlignment: CrossAxisAlignment .start,
137
- children: < Widget > [
138
- Expanded (
139
- child: Text (
140
- searchMealsItem.strMeal,
141
- style: Theme .of (context).textTheme.title,
142
- maxLines: 2 ,
143
- ),
144
- ),
145
- GestureDetector (
146
- onTap: () {
147
- // TODO: do something in here
148
- print ("tap favorite" );
149
- },
150
- child: CircleAvatar (
151
- backgroundColor: Color (0xAFE8364B ),
152
- child: Icon (
153
- Icons .favorite_border,
154
- color: Colors .white,
155
- ),
156
- ),
157
- ),
158
- ],
159
- ),
160
- ),
161
- ],
162
- ),
163
- ),
164
- ),
165
- ),
166
- );
81
+ return CardMeal (searchMealsItem);
167
82
},
168
83
);
169
84
} else if (snapshot.hasError) {
@@ -208,6 +123,147 @@ class _SearchMealsScreenState extends State<SearchMealsScreen> {
208
123
}
209
124
}
210
125
126
+ class CardMeal extends StatefulWidget {
127
+ final SearchMealsItem searchMealsItem;
128
+
129
+ CardMeal (this .searchMealsItem);
130
+
131
+ @override
132
+ _CardMealState createState () => _CardMealState ();
133
+ }
134
+
135
+ class _CardMealState extends State <CardMeal > {
136
+ @override
137
+ Widget build (BuildContext context) {
138
+ var mediaQuery = MediaQuery .of (context);
139
+ return Padding (
140
+ padding: EdgeInsets .only (bottom: 16.0 ),
141
+ child: GestureDetector (
142
+ onTap: () {
143
+ Navigator .push (
144
+ context,
145
+ MaterialPageRoute (
146
+ builder: (context) {
147
+ return DetailMealsScreen (
148
+ widget.searchMealsItem.idMeal,
149
+ widget.searchMealsItem.strMeal,
150
+ widget.searchMealsItem.strMealThumb,
151
+ );
152
+ },
153
+ ),
154
+ );
155
+ },
156
+ child: Card (
157
+ elevation: 8.0 ,
158
+ shape: RoundedRectangleBorder (
159
+ borderRadius: BorderRadius .circular (16.0 ),
160
+ ),
161
+ child: ClipRRect (
162
+ borderRadius: BorderRadius .circular (16.0 ),
163
+ child: Stack (
164
+ children: < Widget > [
165
+ Hero (
166
+ tag: "image_detail_meals_${widget .searchMealsItem .idMeal }" ,
167
+ child: FadeInImage (
168
+ image: NetworkImage (widget.searchMealsItem.strMealThumb),
169
+ placeholder:
170
+ AssetImage ("assets/images/img_placeholder.jpg" ),
171
+ fit: BoxFit .cover,
172
+ width: double .infinity,
173
+ height: mediaQuery.size.width / 1.5 ,
174
+ ),
175
+ ),
176
+ Container (
177
+ width: double .infinity,
178
+ height: mediaQuery.size.width / 1.5 ,
179
+ decoration: BoxDecoration (
180
+ gradient: LinearGradient (
181
+ begin: Alignment .topCenter,
182
+ end: Alignment .bottomCenter,
183
+ stops: [
184
+ 0.1 ,
185
+ 0.9
186
+ ],
187
+ colors: [
188
+ Color (0xFFFFFFFF ),
189
+ Color (0x00FFFFFF ),
190
+ ]),
191
+ ),
192
+ ),
193
+ Padding (
194
+ padding: EdgeInsets .all (16.0 ),
195
+ child: Row (
196
+ crossAxisAlignment: CrossAxisAlignment .start,
197
+ children: < Widget > [
198
+ Expanded (
199
+ child: Text (
200
+ widget.searchMealsItem.strMeal,
201
+ style: Theme .of (context).textTheme.title,
202
+ maxLines: 2 ,
203
+ ),
204
+ ),
205
+ GestureDetector (
206
+ onTap: () {
207
+ var isFavorite = widget.searchMealsItem.isFavorite;
208
+ if (isFavorite) {
209
+ searchMealsBloc
210
+ .deleteFavoriteMealById (
211
+ widget.searchMealsItem.idMeal)
212
+ .then ((status) {
213
+ setState (() {
214
+ widget.searchMealsItem.isFavorite = ! isFavorite;
215
+ });
216
+ });
217
+ } else {
218
+ Future <LookupMealsById > lookupMealsById =
219
+ searchMealsBloc.getDetailMealById (
220
+ widget.searchMealsItem.idMeal);
221
+ lookupMealsById.then ((value) {
222
+ if (value != null ) {
223
+ var item = value.lookupMealsbyIdItems[0 ];
224
+ FavoriteMeal favoriteMeal =
225
+ FavoriteMeal .fromJson (item.toJson ());
226
+ searchMealsBloc
227
+ .addFavoriteMeal (favoriteMeal)
228
+ .then ((status) {
229
+ setState (() {
230
+ widget.searchMealsItem.isFavorite =
231
+ ! isFavorite;
232
+ });
233
+ });
234
+ } else {
235
+ Scaffold .of (context).showSnackBar (SnackBar (
236
+ content:
237
+ Text ("Failed added to favorite meal" )));
238
+ }
239
+ });
240
+ }
241
+ },
242
+ child: CircleAvatar (
243
+ backgroundColor: Color (0xAFE8364B ),
244
+ child: widget.searchMealsItem.isFavorite
245
+ ? Icon (
246
+ Icons .favorite,
247
+ color: Colors .white,
248
+ )
249
+ : Icon (
250
+ Icons .favorite_border,
251
+ color: Colors .white,
252
+ ),
253
+ ),
254
+ ),
255
+ ],
256
+ ),
257
+ ),
258
+ ],
259
+ ),
260
+ ),
261
+ ),
262
+ ),
263
+ );
264
+ }
265
+ }
266
+
211
267
class TextFieldSearch extends StatefulWidget {
212
268
@override
213
269
_TextFieldSearchState createState () => _TextFieldSearchState ();
0 commit comments