@@ -7,18 +7,254 @@ class App extends StatelessWidget {
7
7
@override
8
8
Widget build (BuildContext context) {
9
9
return MaterialApp (
10
+ theme: ThemeData (
11
+ primaryColor: Color (0xFF7D9AFF ),
12
+ accentColor: Color (0xFF7D9AFF ),
13
+ ),
10
14
home: HomeScreen (),
11
15
);
12
16
}
13
17
}
14
18
15
19
class HomeScreen extends StatelessWidget {
20
+ List <Song > listSong = List ();
21
+
16
22
@override
17
23
Widget build (BuildContext context) {
24
+ var mediaQuery = MediaQuery .of (context);
25
+ initListSong ();
26
+
18
27
return Scaffold (
19
- body: Center (
20
- child: Text ('hello world' ),
28
+ body: Stack (
29
+ children: < Widget > [
30
+ _buildWidgetAlbumCover (mediaQuery),
31
+ _buildWidgetActionAppBar (mediaQuery),
32
+ _buildWidgetArtistName (mediaQuery),
33
+ _buildWidgetFloatingActionButton (mediaQuery),
34
+ _buildWidgetListSong (mediaQuery),
35
+ ],
36
+ ),
37
+ );
38
+ }
39
+
40
+ Widget _buildWidgetArtistName (MediaQueryData mediaQuery) {
41
+ return SizedBox (
42
+ height: mediaQuery.size.height / 1.8 ,
43
+ child: Padding (
44
+ padding: const EdgeInsets .only (left: 20.0 ),
45
+ child: LayoutBuilder (
46
+ builder: (BuildContext context, BoxConstraints constraints) {
47
+ return Stack (
48
+ children: < Widget > [
49
+ Positioned (
50
+ child: Text (
51
+ "Grande" ,
52
+ style: TextStyle (
53
+ color: Colors .white,
54
+ fontFamily: "CoralPen" ,
55
+ fontSize: 72.0 ,
56
+ ),
57
+ ),
58
+ top: constraints.maxHeight - 100.0 ,
59
+ ),
60
+ Positioned (
61
+ child: Text (
62
+ "Ariana" ,
63
+ style: TextStyle (
64
+ color: Colors .white,
65
+ fontFamily: "CoralPen" ,
66
+ fontSize: 72.0 ,
67
+ ),
68
+ ),
69
+ top: constraints.maxHeight - 140.0 ,
70
+ ),
71
+ Positioned (
72
+ child: Text (
73
+ "Tranding" ,
74
+ style: TextStyle (
75
+ color: Color (0xFF7D9AFF ),
76
+ fontSize: 14.0 ,
77
+ ),
78
+ ),
79
+ top: constraints.maxHeight - 160.0 ,
80
+ ),
81
+ ],
82
+ );
83
+ },
84
+ ),
85
+ ),
86
+ );
87
+ }
88
+
89
+ Widget _buildWidgetListSong (MediaQueryData mediaQuery) {
90
+ return Padding (
91
+ padding: EdgeInsets .only (
92
+ left: 20.0 ,
93
+ top: mediaQuery.size.height / 1.8 + 48.0 ,
94
+ right: 20.0 ,
95
+ bottom: mediaQuery.padding.bottom + 16.0 ,
96
+ ),
97
+ child: Column (
98
+ children: < Widget > [
99
+ _buildWidgetHeaderSong (),
100
+ SizedBox (height: 16.0 ),
101
+ Expanded (
102
+ child: ListView .separated (
103
+ padding: EdgeInsets .zero,
104
+ separatorBuilder: (BuildContext context, int index) {
105
+ return Opacity (
106
+ opacity: 0.5 ,
107
+ child: Padding (
108
+ padding: const EdgeInsets .only (top: 2.0 ),
109
+ child: Divider (
110
+ color: Colors .grey,
111
+ ),
112
+ ),
113
+ );
114
+ },
115
+ itemCount: listSong.length,
116
+ itemBuilder: (BuildContext context, int index) {
117
+ Song song = listSong[index];
118
+ return Row (
119
+ children: < Widget > [
120
+ Expanded (
121
+ child: Text (
122
+ song.title,
123
+ style: TextStyle (
124
+ color: Colors .black,
125
+ fontWeight: FontWeight .w400,
126
+ ),
127
+ overflow: TextOverflow .ellipsis,
128
+ ),
129
+ ),
130
+ Text (
131
+ song.duration,
132
+ style: TextStyle (
133
+ color: Colors .grey,
134
+ ),
135
+ ),
136
+ SizedBox (width: 24.0 ),
137
+ Icon (
138
+ Icons .more_horiz,
139
+ color: Colors .grey,
140
+ ),
141
+ ],
142
+ );
143
+ },
144
+ ),
145
+ ),
146
+ ],
147
+ ),
148
+ );
149
+ }
150
+
151
+ Widget _buildWidgetHeaderSong () {
152
+ return Row (
153
+ mainAxisAlignment: MainAxisAlignment .spaceBetween,
154
+ children: < Widget > [
155
+ Text (
156
+ "Popular" ,
157
+ style: TextStyle (
158
+ color: Colors .black,
159
+ fontWeight: FontWeight .w500,
160
+ fontSize: 24.0 ,
161
+ ),
162
+ ),
163
+ Text (
164
+ "Show all" ,
165
+ style: TextStyle (
166
+ color: Color (0xFF7D9AFF ),
167
+ fontWeight: FontWeight .w500,
168
+ ),
169
+ ),
170
+ ],
171
+ );
172
+ }
173
+
174
+ Widget _buildWidgetFloatingActionButton (MediaQueryData mediaQuery) {
175
+ return Align (
176
+ alignment: Alignment .topRight,
177
+ child: Padding (
178
+ padding: EdgeInsets .only (
179
+ top: mediaQuery.size.height / 1.8 - 32.0 ,
180
+ right: 32.0 ,
181
+ ),
182
+ child: FloatingActionButton (
183
+ child: Icon (
184
+ Icons .play_arrow,
185
+ color: Colors .white,
186
+ ),
187
+ backgroundColor: Color (0xFF7D9AFF ),
188
+ onPressed: () {
189
+ // TODO: do something in here
190
+ },
191
+ ),
192
+ ),
193
+ );
194
+ }
195
+
196
+ Widget _buildWidgetActionAppBar (MediaQueryData mediaQuery) {
197
+ return Padding (
198
+ padding: EdgeInsets .only (
199
+ left: 16.0 ,
200
+ top: mediaQuery.padding.top + 16.0 ,
201
+ right: 16.0 ,
202
+ ),
203
+ child: Row (
204
+ mainAxisAlignment: MainAxisAlignment .spaceBetween,
205
+ children: < Widget > [
206
+ Icon (
207
+ Icons .menu,
208
+ color: Colors .white,
209
+ ),
210
+ Icon (
211
+ Icons .info_outline,
212
+ color: Colors .white,
213
+ ),
214
+ ],
215
+ ),
216
+ );
217
+ }
218
+
219
+ Widget _buildWidgetAlbumCover (MediaQueryData mediaQuery) {
220
+ return Container (
221
+ width: double .infinity,
222
+ height: mediaQuery.size.height / 1.8 ,
223
+ decoration: BoxDecoration (
224
+ shape: BoxShape .rectangle,
225
+ borderRadius: BorderRadius .only (
226
+ bottomLeft: Radius .circular (48.0 ),
227
+ ),
228
+ image: DecorationImage (
229
+ image:
230
+ AssetImage ("assets/ariana_grande_cover_no_tears_left_to_cry.jpg" ),
231
+ fit: BoxFit .cover,
232
+ ),
21
233
),
22
234
);
23
235
}
236
+
237
+ void initListSong () {
238
+ listSong.add (Song (title: "No tears left to cry" , duration: "5:20" ));
239
+ listSong.add (Song (title: "Imagine" , duration: "3:20" ));
240
+ listSong.add (Song (title: "Into you" , duration: "4:12" ));
241
+ listSong.add (Song (title: "One last time" , duration: "4:40" ));
242
+ listSong.add (Song (title: "7 rings" , duration: "2:58" ));
243
+ listSong.add (Song (title: "Thank u, next" , duration: "3:27" ));
244
+ listSong.add (Song (
245
+ title: "Break up with your girlfriend, i'm bored" , duration: "3:10" ));
246
+ listSong.add (Song (title: "Test" , duration: "0:00" ));
247
+ }
248
+ }
249
+
250
+ class Song {
251
+ String title;
252
+ String duration;
253
+
254
+ Song ({this .title, this .duration});
255
+
256
+ @override
257
+ String toString () {
258
+ return 'Song{title: $title , duration: $duration }' ;
259
+ }
24
260
}
0 commit comments