Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 79b23b8

Browse files
👽️ Create Screen Detail and BarCart
1 parent 30e5f6c commit 79b23b8

File tree

2 files changed

+245
-0
lines changed

2 files changed

+245
-0
lines changed
Lines changed: 165 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,165 @@
1+
import 'package:flutter/material.dart';
2+
import 'package:foods_selection_screen/data/food_data.dart';
3+
import 'package:foods_selection_screen/presentation/detail/widgets/cart_bar.dart';
4+
5+
class DetailScreen extends StatefulWidget {
6+
final Item data;
7+
final String tag;
8+
9+
const DetailScreen({super.key, required this.data, required this.tag});
10+
11+
@override
12+
State<DetailScreen> createState() => _DetailScreenState();
13+
}
14+
15+
class _DetailScreenState extends State<DetailScreen>
16+
with SingleTickerProviderStateMixin {
17+
bool showCart = false;
18+
late final AnimationController _rotationController;
19+
20+
@override
21+
void initState() {
22+
super.initState();
23+
_rotationController = AnimationController(
24+
vsync: this,
25+
duration: const Duration(seconds: 10),
26+
)..repeat();
27+
}
28+
29+
@override
30+
void dispose() {
31+
_rotationController.dispose();
32+
super.dispose();
33+
}
34+
35+
@override
36+
Widget build(BuildContext context) {
37+
return Scaffold(
38+
body: Stack(
39+
children: [
40+
SafeArea(
41+
child: Padding(
42+
padding: const EdgeInsets.symmetric(horizontal: 20),
43+
child: Column(
44+
children: [
45+
_buildHeader(context),
46+
const SizedBox(height: 20),
47+
_buildRotatingFoodImage(),
48+
const Spacer(),
49+
_buildFoodTitle(),
50+
const SizedBox(height: 10),
51+
_buildRating(),
52+
const SizedBox(height: 10),
53+
_buildDescription(),
54+
const Spacer(),
55+
_buildPriceAndCartButton(),
56+
const Spacer(),
57+
],
58+
),
59+
),
60+
),
61+
// _buildCartBar(context),
62+
CartBar(
63+
showCart: showCart,
64+
onClose: () => setState(() => showCart = false),
65+
),
66+
],
67+
),
68+
);
69+
}
70+
71+
Widget _buildHeader(BuildContext context) {
72+
return Row(
73+
mainAxisAlignment: MainAxisAlignment.spaceBetween,
74+
children: [
75+
IconButton(
76+
onPressed: () => Navigator.pop(context),
77+
icon: const Icon(Icons.arrow_back_ios),
78+
),
79+
GestureDetector(
80+
onTap: () => setState(() => showCart = true),
81+
child: CircleAvatar(
82+
radius: 20,
83+
backgroundColor: Theme.of(context).scaffoldBackgroundColor,
84+
child: const Icon(Icons.shopping_cart, color: Colors.black),
85+
),
86+
),
87+
],
88+
);
89+
}
90+
91+
Widget _buildRotatingFoodImage() {
92+
return Center(
93+
child: RotationTransition(
94+
turns: _rotationController,
95+
child: Hero(
96+
tag: widget.tag,
97+
child: CircleAvatar(
98+
radius: 150,
99+
backgroundColor: Colors.transparent,
100+
backgroundImage: AssetImage(widget.data.image),
101+
),
102+
),
103+
),
104+
);
105+
}
106+
107+
Widget _buildFoodTitle() {
108+
return Text(
109+
widget.data.title,
110+
style: const TextStyle(fontWeight: FontWeight.bold, fontSize: 32),
111+
textAlign: TextAlign.center,
112+
);
113+
}
114+
115+
Widget _buildRating() {
116+
return Row(
117+
mainAxisAlignment: MainAxisAlignment.center,
118+
children: List.generate(
119+
5,
120+
(index) => const Icon(Icons.star, color: Colors.orange, size: 20),
121+
),
122+
);
123+
}
124+
125+
Widget _buildDescription() {
126+
return Text(
127+
widget.data.description,
128+
style: TextStyle(fontSize: 16, color: Colors.grey.shade600),
129+
maxLines: 4,
130+
overflow: TextOverflow.ellipsis,
131+
textAlign: TextAlign.center,
132+
);
133+
}
134+
135+
Widget _buildPriceAndCartButton() {
136+
return Row(
137+
mainAxisAlignment: MainAxisAlignment.spaceBetween,
138+
children: [
139+
Text(
140+
"Giá món: ${widget.data.price} đ",
141+
style: const TextStyle(fontSize: 20, fontWeight: FontWeight.bold),
142+
),
143+
ElevatedButton(
144+
onPressed: () {
145+
setState(() => showCart = true);
146+
},
147+
style: ElevatedButton.styleFrom(
148+
backgroundColor: Colors.black,
149+
padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 10),
150+
shape: RoundedRectangleBorder(
151+
borderRadius: BorderRadius.circular(10),
152+
),
153+
),
154+
child: const Text(
155+
"Thêm món",
156+
style: TextStyle(
157+
fontSize: 18,
158+
color: Colors.white,
159+
),
160+
),
161+
),
162+
],
163+
);
164+
}
165+
}
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
import 'package:flutter/material.dart';
2+
import 'package:foods_selection_screen/data/food_data.dart';
3+
4+
class CartBar extends StatelessWidget {
5+
final bool showCart;
6+
final Function() onClose;
7+
8+
const CartBar({
9+
super.key,
10+
required this.showCart,
11+
required this.onClose,
12+
});
13+
14+
@override
15+
Widget build(BuildContext context) {
16+
return AnimatedPositioned(
17+
duration: const Duration(milliseconds: 300),
18+
curve: Curves.easeInOutBack,
19+
right: showCart ? 10 : -150,
20+
top: MediaQuery.sizeOf(context).height * 0.2,
21+
bottom: MediaQuery.sizeOf(context).height * 0.2,
22+
child: Container(
23+
width: 100,
24+
height: MediaQuery.sizeOf(context).height * 0.6,
25+
decoration: BoxDecoration(
26+
color: Colors.white,
27+
borderRadius: BorderRadius.circular(20),
28+
boxShadow: [
29+
BoxShadow(
30+
color: Colors.black.withOpacity(0.1),
31+
blurRadius: 10,
32+
),
33+
],
34+
),
35+
child: SafeArea(
36+
child: Padding(
37+
padding: const EdgeInsets.symmetric(horizontal: 10),
38+
child: Column(
39+
crossAxisAlignment: CrossAxisAlignment.center,
40+
mainAxisAlignment: MainAxisAlignment.center,
41+
children: [
42+
GestureDetector(
43+
onTap: onClose,
44+
child: CircleAvatar(
45+
radius: 22,
46+
backgroundColor: Theme.of(context).scaffoldBackgroundColor,
47+
child: const Icon(Icons.close, color: Colors.black),
48+
),
49+
),
50+
const SizedBox(height: 20),
51+
const Text("Đơn mua",
52+
textAlign: TextAlign.center,
53+
style: TextStyle(fontSize: 18)),
54+
const SizedBox(height: 20),
55+
Expanded(
56+
child: ListView.builder(
57+
itemCount: items.length,
58+
itemBuilder: (context, index) =>
59+
Image.asset(items[index].image, height: 50),
60+
),
61+
),
62+
const SizedBox(height: 20),
63+
const Text("Tổng:",
64+
style:
65+
TextStyle(fontSize: 18, fontWeight: FontWeight.bold)),
66+
Text("${items.length} món",
67+
style: const TextStyle(fontSize: 14)),
68+
const SizedBox(height: 5),
69+
const Text("250.000 đ",
70+
style:
71+
TextStyle(fontSize: 16, fontWeight: FontWeight.w800)),
72+
const SizedBox(height: 20),
73+
],
74+
),
75+
),
76+
),
77+
),
78+
);
79+
}
80+
}

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /