10000 Buat konten di UI Detail Meal · CoderJava/Food-Recipe@516425f · GitHub
[go: up one dir, main page]

Skip to content

Commit 516425f

Browse files
committed
Buat konten di UI Detail Meal
Adapun beberapa konten yang dibuat di UI Detail Meal adalah sebagai berikut 1. Menampilkan judul makanan 2. Menampilkan tag makanan 3. Menampilkan info panel makanan (video, kategori, dan negara) 4. Menampilkan bahan-bahan makanan 5. Menampilkan langkah-langkah membuat makanan
1 parent 98f0d8e commit 516425f

File tree

8 files changed

+360
-38
lines changed

8 files changed

+360
-38
lines changed

lib/src/app.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ class _AppState extends State<App> {
2121
routes: {
2222
navigatorListMeals: (context) {
2323
return ListMealsScreen();
24-
}
24+
},
2525
},
2626
theme: ThemeData(
2727
primaryColor: ColorAssets.primarySwatchColor,
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import 'package:food_recipe/src/models/lookupmealsbyid/lookup_meals_by_id.dart';
2+
import 'package:food_recipe/src/resources/repository.dart';
3+
4+
class DetailsMealsBloc {
5+
final _repository = Repository();
6+
7+
dispose() {
8+
// TODO: do something in here
9+
}
10+
11+
Future<LookupMealsById> getDetailsMealsById(String idMeal) async {
12+
return await _repository.getLookupMealsById(idMeal);
13+
}
14+
15+
}
16+
17+
final detailsMealsBloc = DetailsMealsBloc();
File renamed without changes.

lib/src/blocs/list_meals_bloc.dart renamed to lib/src/blocs/listmeals/list_meals_bloc.dart

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,10 @@ import 'package:food_recipe/src/models/filtercategories/filter_categories.dart';
22
import 'package:food_recipe/src/resources/repository.dart';
33

44
class ListMealsBloc {
5-
final repository = Repository();
5+
final _repository = Repository();
66

77
Future<FilterCategories> getFilterCategories(String category) async {
8-
return await repository.getFilterByCategories(category);
8+
return await _repository.getFilterByCategories(category);
99
}
1010

1111
dispose() {
Lines changed: 282 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,282 @@
1+
import 'package:flutter/cupertino.dart';
2+
import 'package:flutter/material.dart';
3+
import 'package:food_recipe/src/blocs/detailmeals/detail_meals_bloc.dart';
4+
import 'package:food_recipe/src/models/lookupmealsbyid/lookup_meals_by_id.dart';
5+
import 'package:food_recipe/src/utils/utils.dart';
6+
7+
class DetailMealsScreen extends StatefulWidget {
8+
final String idMeal;
9+
final String strMeal;
10+
final String strMealThumb;
11+
12+
DetailMealsScreen(this.idMeal, this.strMeal, this.strMealThumb);
13+
14+
@override
15+
_DetailMealsScreenState createState() => _DetailMealsScreenState();
16+
}
17+
18+
class _DetailMealsScreenState extends State<DetailMealsScreen> {
19+
@override
20+
Widget build(BuildContext context) {
21+
var mediaQuery = MediaQuery.of(context);
22+
return Scaffold(
23+
body: Container(
24+
child: Stack(
25+
children: <Widget>[
26+
_buildWidgetImageHeader(mediaQuery),
27+
_buildWidgetDetailMeal(mediaQuery, context),
28+
],
29+
),
30+
),
31+
);
32+
}
33+
34+
Widget _buildWidgetDetailMeal(
35+
MediaQueryData mediaQuery, BuildContext context) {
36+
return Padding(
37+
padding: EdgeInsets.only(top: mediaQuery.size.height / 2.5),
38+
child: ClipRRect(
39+
borderRadius: BorderRadius.only(
40+
topLeft: Radius.circular(28.0),
41+
topRight: Radius.circular(28.0),
42+
),
43+
child: Container(
44+
width: double.infinity,
45+
color: Colors.white,
46+
child: SafeArea(
47+
left: false,
48+
top: false,
49+
right: false,
50+
child: ListView(
51+
padding: EdgeInsets.only(
52+
left: 16.0,
53+
top: 16.0,
54+
right: 16.0,
55+
),
56+
children: <Widget>[
57+
_buildTitleMeal(context),
58+
_buildWidgetDataDetailMeal(),
59+
],
60+
),
61+
),
62+
),
63+
),
64+
);
65+
}
66+
67+
Widget _buildWidgetDataDetailMeal() {
68+
return FutureBuilder(
69+
future: detailsMealsBloc.getDetailsMealsById(widget.idMeal),
70+
builder: (BuildContext context, AsyncSnapshot<LookupMealsById> snapshot) {
71+
if (snapshot.hasData) {
72+
LookupMealsById lookupMealsById = snapshot.data;
73+
var detailMeals = lookupMealsById.lookupMealsbyIdItems[0];
74+
return Column(
75+
crossAxisAlignment: CrossAxisAlignment.start,
76+
children: <Widget>[
77+
_buildTagMeal(detailMeals.strTags),
78+
Padding(padding: EdgeInsets.only(top: 24.0)),
79+
_buildWidgetPanelInfoGeneralMeal(detailMeals),
80+
Padding(padding: EdgeInsets.only(top: 24.0)),
81+
Text(
82+
"Ingredients",
83+
style: Theme.of(context).textTheme.title,
84+
),
85+
_buildWidgetInfoIngredients(detailMeals),
86+
Padding(padding: EdgeInsets.only(top: 24.0)),
87+
Text(
88+
"Instructions",
89+
style: Theme.of(context).textTheme.title,
90+
),
91+
_buildWidgetInfoInstructions(detailMeals.strInstructions),
92+
],
93+
);
94+
} else if (snapshot.hasError) {
95+
return Text(snapshot.error.toString());
96+
}
97+
return Padding(
98+
padding: const EdgeInsets.only(top: 16.0),
99+
child: Center(child: buildCircularProgressIndicator()),
100+
);
101+
},
102+
);
103+
}
104+
105+
Widget _buildWidgetInfoInstructions(String strInstructions) {
106+
return Padding(
107+
padding: EdgeInsets.only(left: 8.0, top: 8.0),
108+
child: Text(strInstructions),
109+
);
110+
}
111+
112+
Widget _buildWidgetInfoIngredients(LookupMealsByIdItem detailMeals) {
113+
List<String> ingredientsTemp = [];
114+
ingredientsTemp
115+
..add(detailMeals.strMeasure1 + " " + detailMeals.strIngredient1)
116+
..add(detailMeals.strMeasure2 + " " + detailMeals.strIngredient2)
117+
..add(detailMeals.strMeasure3 + " " + detailMeals.strIngredient3)
118+
..add(detailMeals.strMeasure4 + " " + detailMeals.strIngredient4)
119+
..add(detailMeals.strMeasure5 + " " + detailMeals.strIngredient5)
120+
..add(detailMeals.strMeasure6 + " " + detailMeals.strIngredient6)
121+
..add(detailMeals.strMeasure7 + " " + detailMeals.strIngredient7)
122+
..add(detailMeals.strMeasure8 + " " + detailMeals.strIngredient8)
123+
..add(detailMeals.strMeasure9 + " " + detailMeals.strIngredient9)
124+
..add(detailMeals.strMeasure10 + " " + detailMeals.strIngredient10)
125+
..add(detailMeals.strMeasure11 + " " + detailMeals.strIngredient11)
126+
..add(detailMeals.strMeasure12 + " " + detailMeals.strIngredient12)
127+
..add(detailMeals.strMeasure13 + " " + detailMeals.strIngredient13)
128+
..add(detailMeals.strMeasure14 + " " + detailMeals.strIngredient14)
129+
..add(detailMeals.strMeasure15 + " " + detailMeals.strIngredient15)
130+
..add(detailMeals.strMeasure16 + " " + detailMeals.strIngredient16)
131+
..add(detailMeals.strMeasure17 + " " + detailMeals.strIngredient17)
132+
..add(detailMeals.strMeasure18 + " " + detailMeals.strIngredient18)
133+
..add(detailMeals.strMeasure19 + " " + detailMeals.strIngredient19)
134+
..add(detailMeals.strMeasure20 + " " + detailMeals.strIngredient20);
135+
List<String> ingredients = [];
136+
for (String ingredientItem in ingredientsTemp) {
137+
if (ingredientItem.trim().isEmpty) {
138+
break;
139+
}
140+
ingredients.add(ingredientItem);
141+
}
142+
return Padding(
143+
padding: EdgeInsets.only(left: 8.0, top: 8.0),
144+
child: ListView.builder(
145+
padding: EdgeInsets.all(0.0),
146+
shrinkWrap: true,
147+
physics: NeverScrollableScrollPhysics(),
148+
itemCount: ingredients.length,
149+
itemBuilder: (context, index) {
150+
return Row(
151+
crossAxisAlignment: CrossAxisAlignment.center,
152+
children: <Widget>[
153+
Container(
154+
decoration: BoxDecoration(
155+
shape: BoxShape.circle,
156+
color: Colors.black54,
157+
),
158+
width: 6.0,
159+
height: 6.0,
160+
),
161+
Padding(padding: EdgeInsets.only(right: 16.0)),
162+
Text(ingredients[index]),
163+
],
164+
);
165+
},
166+
),
167+
);
168+
}
169+
170+
Widget _buildWidgetPanelInfoGeneralMeal(LookupMealsByIdItem detailMeals) {
171+
return Row(
172+
crossAxisAlignment: CrossAxisAlignment.center,
173+
mainAxisAlignment: MainAxisAlignment.spaceAround,
174+
children: <Widget>[
175+
_buildWidgetInfoPlayVideo(detailMeals.strYoutube),
176+
Padding(padding: EdgeInsets.only(left: 8.0)),
177+
_buildVerticalDivider(),
178+
Padding(padding: EdgeInsets.only(left: 8.0)),
179+
_buildWidgetInfoCategoryMeal(detailMeals.strCategory),
180+
Padding(padding: EdgeInsets.only(left: 8.0)),
181+
_buildVerticalDivider(),
182+
Padding(padding: EdgeInsets.only(left: 8.0)),
183+
_buildWidgetInfoCountryMeal(detailMeals),
184+
Padding(padding: EdgeInsets.only(left: 8.0)),
185+
],
186+
);
187+
}
188+
189+
Widget _buildWidgetInfoCountryMeal(LookupMealsByIdItem detailMeals) {
190+
return Column(
191+
children: <Widget>[
192+
Text("Country"),
193+
Text(detailMeals.strArea,
194+
style: TextStyle(fontWeight: FontWeight.bold)),
195+
],
196+
);
197+
}
198+
199+
Widget _buildWidgetInfoCategoryMeal(String strCategory) {
200+
return Column(
201+
children: <Widget>[
202+
Text("Category"),
203+
Text(strCategory, style: TextStyle(fontWeight: FontWeight.bold)),
204+
],
205+
);
206+
}
207+
208+
Widget _buildVerticalDivider() {
209+
return Container(
210+
color: Colors.grey,
211+
width: 1.0,
212+
height: 42.0,
213+
);
214+
}
215+
216+
Widget _buildWidgetInfoPlayVideo(String strYoutube) {
217+
return GestureDetector(
218+
onTap: () {
219+
// TODO: do something in here
220+
},
221+
child: Row(
222+
children: <Widget>[
223+
Icon(
224+
Icons.ondemand_video,
225+
size: 28.0,
226+
),
227+
Padding(padding: EdgeInsets.only(left: 8.0)),
228+
Column(
229+
children: <Widget>[
230+
Text(strYoutube.isEmpty ? "Video" : "Play"),
231+
Text(
232+
strYoutube.isEmpty ? "N/A" : "Video",
233+
style: TextStyle(fontWeight: FontWeight.bold),
234+
),
235+
],
236+
),
237+
],
238+
),
239+
);
240+
}
241+
242+
Widget _buildTagMeal(String strTags) {
243+
return Row(
244+
children: <Widget>[
245+
Icon(
246+
Icons.label,
247+
color: Colors.black26,
248+
size: 24.0,
249+
),
250+
Padding(padding: EdgeInsets.only(left: 4.0)),
251+
Text(
252+
strTags.substring(0, strTags.length - 1),
253+
style: TextStyle(color: Colors.grey),
254+
),
255+
],
256+
);
257+
}
258+
259+
Widget _buildTitleMeal(BuildContext context) {
260+
return Text(
261+
widget.strMeal,
262+
style: Theme.of(context)
263+
.textTheme
264+
.title
265+
.merge(TextStyle(fontWeight: FontWeight.bold)),
266+
maxLines: 2,
267+
);
268+
}
269+
270+
Widget _buildWidgetImageHeader(MediaQueryData mediaQuery) {
271+
return Hero(
272+
tag: "image_detail_meals_${widget.idMeal}",
273+
child: FadeInImage(
274+
image: NetworkImage(widget.strMealThumb),
275+
placeholder: AssetImage("assets/images/img_placeholder.jpg"),
276+
fit: BoxFit.cover,
277+
width: double.infinity,
278+
height: mediaQuery.size.height / 2.2,
279+
),
280+
);
281+
}
282+
}

0 commit comments

Comments
 (0)
0