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 30e5f6c

Browse files
🥚 Create Screen Home
1 parent 1709ec7 commit 30e5f6c

File tree

4 files changed

+262
-111
lines changed

4 files changed

+262
-111
lines changed

‎foods_selection_screen/lib/main.dart‎

Lines changed: 3 additions & 110 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import 'package:flutter/material.dart';
2+
import 'package:foods_selection_screen/presentation/home/home_screen.dart';
23

34
void main() {
45
runApp(const MyApp());
@@ -7,119 +8,11 @@ void main() {
78
class MyApp extends StatelessWidget {
89
const MyApp({super.key});
910

10-
// This widget is the root of your application.
1111
@override
1212
Widget build(BuildContext context) {
1313
return MaterialApp(
14-
title: 'Flutter Demo',
15-
theme: ThemeData(
16-
// This is the theme of your application.
17-
//
18-
// TRY THIS: Try running your application with "flutter run". You'll see
19-
// the application has a purple toolbar. Then, without quitting the app,
20-
// try changing the seedColor in the colorScheme below to Colors.green
21-
// and then invoke "hot reload" (save your changes or press the "hot
22-
// reload" button in a Flutter-supported IDE, or press "r" if you used
23-
// the command line to start the app).
24-
//
25-
// Notice that the counter didn't reset back to zero; the application
26-
// state is not lost during the reload. To reset the state, use hot
27-
// restart instead.
28-
//
29-
// This works for code too, not just values: Most code changes can be
30-
// tested with just a hot reload.
31-
colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
32-
useMaterial3: true,
33-
),
34-
home: const MyHomePage(title: 'Flutter Demo Home Page'),
35-
);
36-
}
37-
}
38-
39-
class MyHomePage extends StatefulWidget {
40-
const MyHomePage({super.key, required this.title});
41-
42-
// This widget is the home page of your application. It is stateful, meaning
43-
// that it has a State object (defined below) that contains fields that affect
44-
// how it looks.
45-
46-
// This class is the configuration for the state. It holds the values (in this
47-
// case the title) provided by the parent (in this case the App widget) and
48-
// used by the build method of the State. Fields in a Widget subclass are
49-
// always marked "final".
50-
51-
final String title;
52-
53-
@override
54-
State<MyHomePage> createState() => _MyHomePageState();
55-
}
56-
57-
class _MyHomePageState extends State<MyHomePage> {
58-
int _counter = 0;
59-
60-
void _incrementCounter() {
61-
setState(() {
62-
// This call to setState tells the Flutter framework that something has
63-
// changed in this State, which causes it to rerun the build method below
64-
// so that the display can reflect the updated values. If we changed
65-
// _counter without calling setState(), then the build method would not be
66-
// called again, and so nothing would appear to happen.
67-
_counter++;
68-
});
69-
}
70-
71-
@override
72-
Widget build(BuildContext context) {
73-
// This method is rerun every time setState is called, for instance as done
74-
// by the _incrementCounter method above.
75-
//
76-
// The Flutter framework has been optimized to make rerunning build methods
77-
// fast, so that you can just rebuild anything that needs updating rather
78-
// than having to individually change instances of widgets.
79-
return Scaffold(
80-
appBar: AppBar(
81-
// TRY THIS: Try changing the color here to a specific color (to
82-
// Colors.amber, perhaps?) and trigger a hot reload to see the AppBar
83-
// change color while the other colors stay the same.
84-
backgroundColor: Theme.of(context).colorScheme.inversePrimary,
85-
// Here we take the value from the MyHomePage object that was created by
86-
// the App.build method, and use it to set our appbar title.
87-
title: Text(widget.title),
88-
),
89-
body: Center(
90-
// Center is a layout widget. It takes a single child and positions it
91-
// in the middle of the parent.
92-
child: Column(
93-
// Column is also a layout widget. It takes a list of children and
94-
// arranges them vertically. By default, it sizes itself to fit its
95-
// children horizontally, and tries to be as tall as its parent.
96-
//
97-
// Column has various properties to control how it sizes itself and
98-
// how it positions its children. Here we use mainAxisAlignment to
99-
// center the children vertically; the main axis here is the vertical
100-
// axis because Columns are vertical (the cross axis would be
101-
// horizontal).
102-
//
103-
// TRY THIS: Invoke "debug painting" (choose the "Toggle Debug Paint"
104-
// action in the IDE, or press "p" in the console), to see the
105-
// wireframe for each widget.
106-
mainAxisAlignment: MainAxisAlignment.center,
107-
children: <Widget>[
108-
const Text(
109-
'You have pushed the button this many times:',
110-
),
111-
Text(
112-
'$_counter',
113-
style: Theme.of(context).textTheme.headlineMedium,
114-
),
115-
],
116-
),
117-
),
118-
floatingActionButton: FloatingActionButton(
119-
onPressed: _incrementCounter,
120-
tooltip: 'Increment',
121-
child: const Icon(Icons.add),
122-
), // This trailing comma makes auto-formatting nicer for build methods.
14+
theme: ThemeData(scaffoldBackgroundColor: const Color(0xffebecf1)),
15+
home: const HomeScreen(),
12316
);
12417
}
12518
}
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
import 'package:flutter/material.dart';
2+
import 'package:foods_selection_screen/data/food_data.dart';
3+
import 'widgets/menu_item_card.dart';
4+
5+
class HomeScreen extends StatelessWidget {
6+
const HomeScreen({super.key});
7+
8+
@override
9+
Widget build(BuildContext context) {
10+
return Scaffold(
11+
appBar: AppBar(
12+
backgroundColor: Colors.transparent,
13+
elevation: 0,
14+
leading: const Icon(Icons.sort, color: Colors.black),
15+
actions: [
16+
_buildActionIcon(context, Icons.shopping_cart),
17+
_buildActionIcon(context, Icons.search,
18+
margin: const EdgeInsets.only(right: 20)),
19+
],
20+
),
21+
body: Padding(
22+
padding: const EdgeInsets.all(20),
23+
child: Column(
24+
crossAxisAlignment: CrossAxisAlignment.start,
25+
children: [
26+
const Text(
27+
"MENU",
28+
style: TextStyle(
29+
fontSize: 40,
30+
fontWeight: FontWeight.bold,
31+
),
32+
),
33+
const SizedBox(height: 8),
34+
Text(
35+
"Đã đến lúc tận hưởng những điều tốt đẹp hơn trong cuộc sống",
36+
style: TextStyle(
37+
fontWeight: FontWeight.w500,
38+
color: Colors.grey.shade700,
39+
fontSize: 16,
40+
),
41+
),
42+
const SizedBox(height: 20),
43+
Expanded(
44+
child: GridView.builder(
45+
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
46+
crossAxisCount: 2,
47+
crossAxisSpacing: 15,
48+
mainAxisSpacing: 15,
49+
childAspectRatio: 0.55,
50+
),
51+
itemCount: items.length,
52+
itemBuilder: (context, index) {
53+
return MenuItemCard(data: items[index], index: index);
54+
},
55+
),
56+
),
57+
],
58+
),
59+
),
60+
);
61+
}
62+
63+
Widget _buildActionIcon(BuildContext context, IconData icon,
64+
{EdgeInsets? margin}) {
65+
return Container(
66+
height: 40,
67+
width: 40,
68+
margin: margin ?? const EdgeInsets.only(right: 15),
69+
decoration: BoxDecoration(
70+
color: Theme.of(context).scaffoldBackgroundColor,
71+
shape: BoxShape.circle,
72+
boxShadow: [
73+
BoxShadow(
74+
color: Colors.black26.withOpacity(0.2),
75+
offset: const Offset(2, 4),
76+
blurRadius: 6,
77+
),
78+
const BoxShadow(
79+
color: Colors.white70,
80+
offset: Offset(-2, -4),
81+
blurRadius: 6,
82+
),
83+
],
84+
),
85+
child: Icon(icon, color: Colors.black),
86+
);
87+
}
88+
}
Lines changed: 169 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,169 @@
1+
import 'package:flutter/material.dart';
2+
import 'package:foods_selection_screen/data/food_data.dart';
3+
import 'package:foods_selection_screen/presentation/detail/detail_screen.dart';
4+
5+
class MenuItemCard extends StatefulWidget {
6+
final Item data;
7+
final int index;
8+
9+
const MenuItemCard({super.key, required this.data, required this.index});
10+
11+
@override
12+
State<MenuItemCard> createState() => _MenuItemCardState();
13+
}
14+
15+
class _MenuItemCardState extends State<MenuItemCard>
16+
with SingleTickerProviderStateMixin {
17+
late AnimationController _controller;
18+
19+
@override
20+
void initState() {
21+
super.initState();
22+
_controller = AnimationController(
23+
duration: const Duration(seconds: 5),
24+
vsync: this,
25+
)..repeat();
26+
}
27+
28+
@override
29+
void dispose() {
30+
_controller.dispose();
31+
super.dispose();
32+
}
33+
34+
@override
35+
Widget build(BuildContext context) {
36+
return GestureDetector(
37+
onTap: () {
38+
Navigator.push(
39+
context,
40+
MaterialPageRoute(
41+
builder: (context) =>
42+
DetailScreen(data: widget.data, tag: "${widget.index}"),
43+
),
44+
);
45+
},
46+
child: Stack(
47+
children: [
48+
Positioned(
49+
top: 50,
50+
right: 0,
51+
left: 0,
52+
bottom: 0,
53+
child: ClipRRect(
54+
borderRadius: BorderRadius.circular(20),
55+
child: Container(
56+
padding: const EdgeInsets.all(15),
57+
decoration: BoxDecoration(
58+
color: Colors.white,
59+
borderRadius: BorderRadius.circular(20),
60+
boxShadow: [
61+
BoxShadow(
62+
color: Colors.black26.withOpacity(0.1),
63+
offset: const Offset(4, 4),
64+
blurRadius: 10,
65+
),
66+
BoxShadow(
67+
color: Colors.white.withOpacity(0.8),
68+
offset: const Offset(-4, -4),
69+
blurRadius: 10,
70+
),
71+
],
72+
),
73+
child: Column(
74+
crossAxisAlignment: CrossAxisAlignment.center,
75+
mainAxisAlignment: MainAxisAlignment.end,
76+
children: [
77+
Text(
78+
widget.data.title,
79+
style: const TextStyle(
80+
fontWeight: FontWeight.bold,
81+
fontSize: 18,
82+
),
83+
textAlign: TextAlign.center,
84+
maxLines: 2,
85+
overflow: TextOverflow.ellipsis,
86+
),
87+
const SizedBox(height: 5),
88+
Text(
89+
"${widget.data.price} đ",
90+
style: TextStyle(
91+
fontSize: 16,
92+
color: Colors.grey.shade800,
93+
),
94+
),
95+
const SizedBox(height: 5),
96+
Row(
97+
mainAxisAlignment: MainAxisAlignment.center,
98+
children: List.generate(
99+
5,
100+
(s) => const Icon(
101+
Icons.star,
102+
color: Colors.orange,
103+
size: 15,
104+
),
105+
),
106+
),
107+
const SizedBox(height: 10),
108+
_buildAddToCartButton(),
109+
],
110+
),
111+
),
112+
),
113+
),
114+
Positioned(
115+
top: -12.5,
116+
right: 0,
117+
left: 0,
118+
child: RotationTransition(
119+
turns: _controller,
120+
child: CircleAvatar(
121+
radius: 75,
122+
backgroundColor: Colors.transparent,
123+
child: Hero(
124+
tag: "${widget.index}",
125+
child: Image.asset(
126+
widget.data.image,
127+
fit: BoxFit.cover,
128+
),
129+
),
130+
),
131+
),
132+
),
133+
],
134+
),
135+
);
136+
}
137+
138+
Widget _buildAddToCartButton() {
139+
return Container(
140+
margin: const EdgeInsets.symmetric(vertical: 10),
141+
padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 5),
142+
decoration: BoxDecoration(
143+
color: Colors.white,
144+
border: Border.all(color: Colors.grey.shade400),
145+
borderRadius: BorderRadius.circular(30),
146+
boxShadow: [
147+
BoxShadow(
148+
color: Colors.black26.withOpacity(0.1),
149+
offset: const Offset(2, 2),
150+
blurRadius: 5,
151+
),
152+
const BoxShadow(
153+
color: Colors.white70,
154+
offset: Offset(-2, -2),
155+
blurRadius: 5,
156+
),
157+
],
158+
),
159+
child: Text(
160+
"Gọi món",
161+
style: TextStyle(
162+
color: Colors.grey.shade800,
163+
fontWeight: FontWeight.bold,
164+
fontSize: 14,
165+
),
166+
),
167+
);
168+
}
169+
}

‎foods_selection_screen/pubspec.yaml‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,8 @@ flutter:
5959
uses-material-design: true
6060

6161
# To add assets to your application, add an assets section, like this:
62-
# assets:
62+
assets:
63+
- assets/
6364
# - images/a_dot_burr.jpeg
6465
# - images/a_dot_ham.jpeg
6566

0 commit comments

Comments
(0)

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