Created
June 9, 2022 13:47
-
-
Save koboolean/0e0a0d38cb3cc93bc5c9f0b437acb4a1 to your computer and use it in GitHub Desktop.
flutter shazam pad
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import 'package:flutter/material.dart'; | |
void main() { | |
runApp(const MyApp()); | |
} | |
class MyApp extends StatelessWidget { | |
const MyApp({Key? key}) : super(key: key); | |
// This widget is the root of your application. | |
@override | |
Widget build(BuildContext context) { | |
return MaterialApp( | |
title: 'Shazam', | |
theme: ThemeData( | |
primarySwatch: Colors.blue, | |
), | |
home: HomePage(), | |
); | |
} | |
} | |
class HomePage extends StatefulWidget { | |
const HomePage({Key? key}) : super(key: key); | |
@override | |
State<HomePage> createState() => _HomePageState(); | |
} | |
class _HomePageState extends State<HomePage> | |
with SingleTickerProviderStateMixin { | |
late final TabController _tabController; | |
int _seletedIndex = 1; | |
@override | |
void initState() { | |
super.initState(); | |
_tabController = TabController(length: 3, vsync: this); | |
_tabController.index = 1; | |
_tabController.addListener(() { | |
setState(() { | |
_seletedIndex = _tabController.index; | |
}); | |
}); | |
} | |
@override | |
Widget build(BuildContext context) { | |
const songs = [ | |
{ | |
'imageUrl': 'https://i.ytimg.com/vi/jAO0KXRdz_4/hqdefault.jpg', | |
'title': '가을밤에 든 생각', | |
'artist': '잔나비', | |
}, | |
{ | |
'imageUrl': 'https://i.ytimg.com/vi/jAO0KXRdz_4/hqdefault.jpg', | |
'title': '가을밤에 든 생각', | |
'artist': '잔나비', | |
}, | |
{ | |
'imageUrl': 'https://i.ytimg.com/vi/jAO0KXRdz_4/hqdefault.jpg', | |
'title': '가을밤에 든 생각', | |
'artist': '잔나비', | |
}, | |
{ | |
'imageUrl': 'https://i.ytimg.com/vi/jAO0KXRdz_4/hqdefault.jpg', | |
'title': '가을밤에 든 생각', | |
'artist': '잔나비', | |
}, | |
{ | |
'imageUrl': 'https://i.ytimg.com/vi/jAO0KXRdz_4/hqdefault.jpg', | |
'title': '가을밤에 든 생각', | |
'artist': '잔나비', | |
}, | |
{ | |
'imageUrl': 'https://i.ytimg.com/vi/jAO0KXRdz_4/hqdefault.jpg', | |
'title': '가을밤에 든 생각', | |
'artist': '잔나비', | |
}, | |
]; | |
return Scaffold( | |
body: Stack( | |
children: [ | |
TabBarView( | |
controller: _tabController, | |
children: [ | |
SafeArea( | |
child: Padding( | |
padding: const EdgeInsets.symmetric(horizontal: 16), | |
child: Column( | |
children: [ | |
Row( | |
mainAxisAlignment: MainAxisAlignment.spaceBetween, | |
crossAxisAlignment: CrossAxisAlignment.start, | |
children: [ | |
Padding( | |
padding: const EdgeInsets.symmetric(vertical: 4.0), | |
child: Icon(Icons.settings), | |
), | |
Text( | |
"라이브러리", | |
textAlign: TextAlign.center, | |
style: TextStyle( | |
fontSize: 18, | |
fontWeight: FontWeight.bold, | |
), | |
), | |
Icon(null), | |
], | |
), | |
SizedBox(height: 8), | |
Padding( | |
padding: const EdgeInsets.symmetric(vertical: 8.0), | |
child: Row( | |
children: [ | |
Container( | |
child: ImageIcon( | |
NetworkImage( | |
"https://cdn.iconscout.com/icon/free/png-256/shazam-3-761709.png", | |
), | |
size: 18, | |
), | |
width: 24, | |
), | |
SizedBox(width: 8), | |
Text( | |
'Shazam', | |
style: TextStyle( | |
fontSize: 18, | |
fontWeight: FontWeight.w600, | |
), | |
), | |
], | |
), | |
), | |
Divider(), | |
Padding( | |
padding: const EdgeInsets.symmetric(vertical: 8.0), | |
child: Row( | |
children: [ | |
Icon(Icons.person_rounded), | |
SizedBox(width: 8), | |
Text( | |
'아티스트', | |
style: TextStyle( | |
fontSize: 18, | |
fontWeight: FontWeight.w600, | |
), | |
), | |
], | |
), | |
), | |
Divider(), | |
Padding( | |
padding: const EdgeInsets.symmetric(vertical: 8.0), | |
child: Row( | |
children: [ | |
Icon(Icons.music_note), | |
SizedBox(width: 8), | |
Text( | |
'회원님을 위한 재생 목록', | |
style: TextStyle( | |
fontSize: 18, | |
fontWeight: FontWeight.w600, | |
), | |
), | |
], | |
), | |
), | |
Padding( | |
padding: const EdgeInsets.symmetric(vertical: 16.0), | |
child: Container( | |
alignment: Alignment.topLeft, | |
child: Text( | |
'최근 Shazam', | |
style: TextStyle( | |
fontSize: 18, | |
fontWeight: FontWeight.w700, | |
), | |
), | |
), | |
), | |
Expanded( | |
child: Column( | |
children: [ | |
Expanded( | |
child: GridView.builder( | |
gridDelegate: | |
SliverGridDelegateWithFixedCrossAxisCount( | |
crossAxisCount: 2, | |
childAspectRatio: 3 / 5), | |
itemCount: songs.length, | |
itemBuilder: (context, index) { | |
String imageUrl = songs[index]['imageUrl']!; | |
String title = songs[index]['title']!; | |
String artist = songs[index]['artist']!; | |
return Padding( | |
padding: const EdgeInsets.all(2.0), | |
child: Container( | |
margin: EdgeInsets.only( | |
left: index % 2 == 1 ? 8 : 0, | |
right: index % 2 == 0 ? 8 : 0, | |
top: 8, | |
bottom: 8, | |
), | |
decoration: BoxDecoration( | |
color: Colors.white, | |
borderRadius: BorderRadius.all( | |
Radius.circular(8), | |
), | |
boxShadow: [ | |
BoxShadow( | |
color: Colors.grey.withOpacity(0.5), | |
blurRadius: 1, | |
spreadRadius: 1, | |
) | |
], | |
), | |
child: Column( | |
crossAxisAlignment: | |
CrossAxisAlignment.start, | |
children: [ | |
ClipRRect( | |
borderRadius: BorderRadius.only( | |
topLeft: Radius.circular(8), | |
topRight: Radius.circular(8), | |
), | |
child: Image.network( | |
imageUrl, | |
fit: BoxFit.fitHeight, | |
height: MediaQuery.of(context) | |
.size | |
.width * | |
0.4, | |
), | |
), | |
Expanded( | |
child: Padding( | |
padding: | |
const EdgeInsets.all(6.0), | |
child: Stack( | |
children: [ | |
Column( | |
crossAxisAlignment: | |
CrossAxisAlignment | |
.start, | |
children: [ | |
Text( | |
title, | |
style: TextStyle( | |
fontSize: 18, | |
fontWeight: | |
FontWeight.bold, | |
), | |
), | |
Text( | |
artist, | |
style: TextStyle( | |
fontSize: 14, | |
fontWeight: | |
FontWeight.normal, | |
color: | |
Colors.grey[600], | |
), | |
), | |
], | |
), | |
Positioned( | |
bottom: 5, | |
child: Image.network( | |
'https://images.squarespace-cdn.com/content/v1/5b31aa3a2487fddecb16c83d/1571241639561-RZS5N4CB4VQT3BEH3L1B/applemusic.png', | |
width: 60, | |
), | |
) | |
], | |
), | |
), | |
), | |
], | |
), | |
), | |
); | |
}, | |
), | |
), | |
], | |
), | |
), | |
], | |
), | |
), | |
), | |
Container( | |
decoration: BoxDecoration( | |
gradient: LinearGradient( | |
begin: Alignment.topCenter, | |
end: Alignment.bottomCenter, | |
colors: [Colors.blue[300]!, Colors.blue[900]!], | |
), | |
), | |
child: SafeArea( | |
child: Column( | |
children: [ | |
Padding( | |
padding: const EdgeInsets.symmetric( | |
vertical: 8, horizontal: 16), | |
child: Row( | |
children: [ | |
GestureDetector( | |
onTap: () { | |
_tabController.index = 0; | |
}, | |
child: Column( | |
children: [ | |
Icon(Icons.person, color: Colors.white), | |
Text( | |
'라이브러리', | |
style: TextStyle(color: Colors.white), | |
), | |
], | |
), | |
), | |
Spacer(), | |
GestureDetector( | |
onTap: () { | |
_tabController.index = 2; | |
}, | |
child: Column( | |
children: [ | |
Icon(Icons.show_chart, color: Colors.white), | |
Text( | |
'차트', | |
style: TextStyle(color: Colors.white), | |
), | |
], | |
), | |
), | |
], | |
), | |
), | |
SizedBox( | |
height: MediaQuery.of(context).size.height * 0.1, | |
), | |
Text( | |
'Shazam하려면 탭하세요', | |
style: TextStyle( | |
color: Colors.white, | |
fontSize: 24, | |
fontWeight: FontWeight.bold, | |
), | |
), | |
SizedBox( | |
height: MediaQuery.of(context).size.height * 0.06, | |
), | |
Container( | |
alignment: Alignment.center, | |
width: 200, | |
height: 200, | |
decoration: BoxDecoration( | |
color: Colors.blue[300], | |
shape: BoxShape.circle, | |
), | |
child: Image.network( | |
"https://cdn.iconscout.com/icon/free/png-256/shazam-3-761709.png", | |
color: Colors.white, | |
width: 130, | |
height: 130, | |
), | |
), | |
SizedBox( | |
height: MediaQuery.of(context).size.height * 0.12, | |
), | |
Container( | |
width: 50, | |
height: 50, | |
alignment: Alignment.center, | |
decoration: BoxDecoration( | |
color: Colors.blue[400], | |
shape: BoxShape.circle, | |
), | |
child: Icon( | |
Icons.search, | |
color: Colors.white, | |
size: 30, | |
), | |
) | |
], | |
), | |
), | |
), | |
SafeArea( | |
child: Column( | |
children: [ | |
Text( | |
'차트', | |
style: TextStyle( | |
color: Colors.black, | |
fontWeight: FontWeight.bold, | |
fontSize: 18, | |
), | |
), | |
SizedBox(height: 16), | |
Expanded( | |
child: SingleChildScrollView( | |
child: Column( | |
children: [ | |
Stack( | |
alignment: Alignment.center, | |
children: [ | |
Container( | |
width: double.infinity, | |
height: 180, | |
color: Colors.purple[900], | |
), | |
Column( | |
children: [ | |
Container( | |
width: MediaQuery.of(context).size.width * | |
0.8, | |
child: ElevatedButton( | |
onPressed: () {}, | |
style: ButtonStyle( | |
backgroundColor: | |
MaterialStateProperty.all( | |
Colors.white), | |
), | |
child: Text( | |
'국가 및 도시별 차트', | |
style: TextStyle( | |
color: Colors.purple[900], | |
fontWeight: FontWeight.bold, | |
), | |
), | |
), | |
), | |
Padding( | |
padding: const EdgeInsets.all(8.0), | |
child: Text( | |
'전 세계', | |
style: TextStyle( | |
color: Colors.white, | |
fontWeight: FontWeight.bold, | |
), | |
), | |
), | |
], | |
), | |
], | |
), | |
Container( | |
width: double.infinity, | |
height: 8, | |
color: Colors.grey[400], | |
), | |
Padding( | |
padding: const EdgeInsets.all(8.0), | |
child: Row( | |
children: [ | |
Text( | |
'대한민국 차트', | |
style: TextStyle(fontSize: 16), | |
), | |
Spacer(), | |
Text( | |
'모두 보기', | |
style: TextStyle(color: Colors.blue), | |
), | |
], | |
), | |
), | |
Row( | |
mainAxisAlignment: MainAxisAlignment.spaceBetween, | |
children: [ | |
AlbumCard( | |
imageUrl: | |
'https://ibighit.com/bts/images/bts/discography/dynamite/Q7gBkUusiDcIYljQOMX9ow6W.jpg', | |
name: 'Dynamite', | |
artist: 'BTS', | |
), | |
AlbumCard( | |
imageUrl: | |
'https://ibighit.com/bts/images/bts/discography/dynamite/Q7gBkUusiDcIYljQOMX9ow6W.jpg', | |
name: 'Dynamite', | |
artist: 'BTS', | |
), | |
AlbumCard( | |
imageUrl: | |
'https://ibighit.com/bts/images/bts/discography/dynamite/Q7gBkUusiDcIYljQOMX9ow6W.jpg', | |
name: 'Dynamite', | |
artist: 'BTS', | |
), | |
], | |
), | |
Container( | |
width: double.infinity, | |
height: 8, | |
color: Colors.grey[400], | |
), | |
Padding( | |
padding: const EdgeInsets.all(8.0), | |
child: Row( | |
children: [ | |
Text( | |
'글로벌 차트', | |
style: TextStyle(fontSize: 16), | |
), | |
Spacer(), | |
Text( | |
'모두 보기', | |
style: TextStyle(color: Colors.blue), | |
), | |
], | |
), | |
), | |
Row( | |
mainAxisAlignment: MainAxisAlignment.spaceBetween, | |
children: [ | |
AlbumCard( | |
imageUrl: | |
'https://ibighit.com/bts/images/bts/discography/dynamite/Q7gBkUusiDcIYljQOMX9ow6W.jpg', | |
name: 'Dynamite', | |
artist: 'BTS', | |
), | |
AlbumCard( | |
imageUrl: | |
'https://ibighit.com/bts/images/bts/discography/dynamite/Q7gBkUusiDcIYljQOMX9ow6W.jpg', | |
name: 'Dynamite', | |
artist: 'BTS', | |
), | |
AlbumCard( | |
imageUrl: | |
'https://ibighit.com/bts/images/bts/discography/dynamite/Q7gBkUusiDcIYljQOMX9ow6W.jpg', | |
name: 'Dynamite', | |
artist: 'BTS', | |
), | |
], | |
), | |
Container( | |
width: double.infinity, | |
height: 8, | |
color: Colors.grey[400], | |
), | |
Padding( | |
padding: const EdgeInsets.all(8.0), | |
child: Row( | |
children: [ | |
Text( | |
'뉴욕 차트', | |
style: TextStyle(fontSize: 16), | |
), | |
Spacer(), | |
Text( | |
'모두 보기', | |
style: TextStyle(color: Colors.blue), | |
), | |
], | |
), | |
), | |
Row( | |
mainAxisAlignment: MainAxisAlignment.spaceBetween, | |
children: [ | |
AlbumCard( | |
imageUrl: | |
'https://ibighit.com/bts/images/bts/discography/dynamite/Q7gBkUusiDcIYljQOMX9ow6W.jpg', | |
name: 'Dynamite', | |
artist: 'BTS', | |
), | |
AlbumCard( | |
imageUrl: | |
'https://ibighit.com/bts/images/bts/discography/dynamite/Q7gBkUusiDcIYljQOMX9ow6W.jpg', | |
name: 'Dynamite', | |
artist: 'BTS', | |
), | |
AlbumCard( | |
imageUrl: | |
'https://ibighit.com/bts/images/bts/discography/dynamite/Q7gBkUusiDcIYljQOMX9ow6W.jpg', | |
name: 'Dynamite', | |
artist: 'BTS', | |
), | |
], | |
), | |
], | |
), | |
), | |
), | |
], | |
), | |
), | |
], | |
), | |
SafeArea( | |
child: Padding( | |
padding: const EdgeInsets.symmetric(vertical: 20, horizontal: 16), | |
child: Column( | |
// crossAxisAlignment: CrossAxisAlignment.center, | |
children: [ | |
Container( | |
alignment: Alignment.topCenter, | |
child: TabPageSelector( | |
color: _seletedIndex == 1 | |
? Colors.blue[300] | |
: Colors.grey[400], | |
selectedColor: | |
_seletedIndex == 1 ? Colors.white : Colors.blue, | |
controller: _tabController, | |
indicatorSize: 8, | |
), | |
), | |
], | |
), | |
), | |
), | |
], | |
), | |
); | |
} | |
} | |
class AlbumCard extends StatelessWidget { | |
const AlbumCard( | |
{Key? key, | |
required this.imageUrl, | |
required this.name, | |
required this.artist}) | |
: super(key: key); | |
final String imageUrl; | |
final String name; | |
final String artist; | |
@override | |
Widget build(BuildContext context) { | |
// TODO: implement build | |
return Padding( | |
padding: const EdgeInsets.all(8.0), | |
child: Column( | |
crossAxisAlignment: CrossAxisAlignment.start, | |
children: [ | |
Image.network( | |
imageUrl, | |
width: MediaQuery.of(context).size.width * 0.29, | |
), | |
Text( | |
name, | |
style: TextStyle(fontWeight: FontWeight.bold), | |
), | |
Text(artist), | |
], | |
), | |
); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment