挨拶
こんにちは 皆さん!Dreamwalkerです。
明けましておめでとうございます。
令和2年の初投稿になります。
ほぼ2ヶ月ぶりに書き始めることになってしまいました。泣
今回のデザイン
今回は14番目の「DribbbleのデザインをFlutterでやってみた」になります。
Monochrome Shop App
結果
一つ目のページ。
二つ目のページ。
三つ目のページ。
必要なライブラリー
1.flutter_staggered_grid_view: ^0.3.0
全てのコード
main。
main.dart
import 'package:flutter/material.dart';
void main() => runApp(MonochromeShopApp());
MaterialApp Importer。
home_page.dart
class MonochromeShopApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: MonochromeShopHome(),
);
}
}
一つ目のページ。
個人的にお気に入りのデザインになります。
AppBarのタイトルはイメージがないので、Widgetで作ってみました。
ShopMainPage
main_page.dart
class MonochromeShopHome extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
body: Stack(
children: <Widget>[
Positioned(
top: 34,
left: 16,
right: 16,
child: Container(
height: 100,
child: Stack(
children: <Widget>[
Center(
child: Text(
"LOSER",
style: TextStyle(
fontSize: 64,
letterSpacing: -6,
fontWeight: FontWeight.bold,
),
),
),
Center(
child: Text(
"V",
style: TextStyle(
fontSize: 84,
letterSpacing: -8,
color: Colors.red,
fontWeight: FontWeight.bold,
),
),
)
],
),
),
),
Positioned(
bottom: 32,
right: 24,
child: GestureDetector(
onTap: () {
Navigator.of(context).push(MaterialPageRoute(
builder: (context) => WomensBlazersPage()));
},
child: Container(
height: 86,
width: 86,
decoration:
BoxDecoration(shape: BoxShape.circle, border: Border.all()),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Text(
"explore",
style: TextStyle(fontSize: 16),
),
SizedBox(
height: 4,
),
Icon(
Icons.arrow_forward,
size: 20,
),
],
),
),
),
),
Positioned(
left: 4,
bottom: 4,
child: Container(
width: MediaQuery.of(context).size.width / 2,
height: MediaQuery.of(context).size.height / 3,
decoration: BoxDecoration(
color: Colors.black,
image: DecorationImage(
image: NetworkImage(
"https://cdn.pixabay.com/photo/2014/01/04/14/35/fashion-238553__340.jpg"),
fit: BoxFit.cover)),
),
),
Positioned(
right: 0,
bottom: MediaQuery.of(context).size.height / 3.5,
child: Container(
width: MediaQuery.of(context).size.width / 1.4,
height: MediaQuery.of(context).size.height / 2.8,
decoration: BoxDecoration(
color: Colors.black,
image: DecorationImage(
image: NetworkImage(
"https://cdn.pixabay.com/photo/2016/06/17/09/54/beauty-1462986__340.jpg"),
fit: BoxFit.cover,
),
border: Border.all(color: Colors.white, width: 5)),
),
),
Positioned(
left: 0,
top: 136,
child: Container(
width: MediaQuery.of(context).size.width / 2.4,
height: MediaQuery.of(context).size.height / 3.4,
decoration: BoxDecoration(
color: Colors.black,
border: Border.all(color: Colors.white, width: 5),
image: DecorationImage(
colorFilter:
ColorFilter.mode(Colors.black, BlendMode.color),
image: NetworkImage(
"https://cdn.pixabay.com/photo/2016/03/09/10/22/two-women-1246024__340.jpg"),
fit: BoxFit.cover)),
),
),
Positioned(
left: MediaQuery.of(context).size.width / 2.4 + 16,
top: 136,
right: 0,
child: Container(
height: 120,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: <Widget>[
Text(
"Men's",
style: TextStyle(fontSize: 18),
),
Text(
"Blazers",
style: TextStyle(fontSize: 18),
)
],
),
),
),
Positioned(
left: 16,
top: MediaQuery.of(context).size.height / 2,
child: Container(
height: 100,
width: 100,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
Text(
"Women's",
style: TextStyle(fontSize: 18),
),
Text(
"Blazers",
style: TextStyle(fontSize: 18),
),
],
),
),
),
Positioned(
right: 16,
left: MediaQuery.of(context).size.width / 2 + 24,
bottom: 120,
child: Container(
height: 80,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: <Widget>[
Text(
"Kid's",
style: TextStyle(fontSize: 18),
),
Text(
"Blazers",
style: TextStyle(fontSize: 18),
)
],
),
),
)
],
),
);
}
}
二つ目のページ。
GridViewが魅力的で今回のポイントになります。
entered_page.dart
import 'package:flutter/material.dart';
import 'package:flutter_notebook_4th/ep355_monochrome_shop_app/detail_page.dart';
import 'package:flutter_staggered_grid_view/flutter_staggered_grid_view.dart';
class Wear {
String img;
String price;
String name;
Wear({this.img, this.price, this.name});
}
List<Wear> items = [
Wear(
img:
"https://cdn.pixabay.com/photo/2017/08/06/09/51/blazer-2590798__340.jpg",
price: "134",
name: "Retro Blazer"),
Wear(
img:
"https://cdn.pixabay.com/photo/2017/08/10/08/00/suit-2619784__340.jpg",
price: "365",
name: "Fashion Blazer"),
Wear(
img:
"https://cdn.pixabay.com/photo/2016/07/19/10/48/girl-1527959__340.jpg",
price: "428",
name: "Classic Blazer"),
Wear(
img:
"https://cdn.pixabay.com/photo/2016/03/23/08/34/beautiful-1274361__340.jpg",
price: "122",
name: "Modern Blazer"),
Wear(
img:
"https://cdn.pixabay.com/photo/2017/08/06/09/51/blazer-2590798__340.jpg",
price: "134",
name: "Retro Blazer"),
Wear(
img:
"https://cdn.pixabay.com/photo/2017/08/06/09/51/blazer-2590798__340.jpg",
price: "134",
name: "Retro Blazer"),
Wear(
img:
"https://cdn.pixabay.com/photo/2016/07/19/10/48/girl-1527959__340.jpg",
price: "428",
name: "Classic Blazer"),
Wear(
img:
"https://cdn.pixabay.com/photo/2016/03/23/08/34/beautiful-1274361__340.jpg",
price: "122",
name: "Modern Blazer"),
Wear(
img:
"https://cdn.pixabay.com/photo/2016/07/19/10/48/girl-1527959__340.jpg",
price: "428",
name: "Classic Blazer"),
Wear(
img:
"https://cdn.pixabay.com/photo/2016/03/23/08/34/beautiful-1274361__340.jpg",
price: "122",
name: "Modern Blazer"),
Wear(
img:
"https://cdn.pixabay.com/photo/2016/07/19/10/48/girl-1527959__340.jpg",
price: "428",
name: "Classic Blazer"),
Wear(
img:
"https://cdn.pixabay.com/photo/2016/03/23/08/34/beautiful-1274361__340.jpg",
price: "122",
name: "Modern Blazer"),
];
class WomensBlazersPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
body: SafeArea(
child: Column(
children: <Widget>[
Expanded(
flex: 2,
child: Padding(
padding: const EdgeInsets.only(right: 16, left: 16),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Icon(
Icons.arrow_back,
color: Colors.grey.shade500,
),
Text(
"Women's Blazers",
style: TextStyle(fontSize: 18, color: Colors.black87),
),
Icon(
Icons.search,
color: Colors.grey.shade500,
),
],
),
),
),
Expanded(
flex: 13,
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 16),
child: StaggeredGridView.countBuilder(
itemBuilder: (context, index) {
return GestureDetector(
onTap: (){
Navigator.push(context, MaterialPageRoute(
builder: (context)=>ItemDetailPage(
wear: items[index],
)
));
},
child: Container(
child: Column(
children: <Widget>[
Expanded(
flex: 8,
child: Container(
decoration: BoxDecoration(
image: DecorationImage(
image: NetworkImage(items[index].img),
fit: BoxFit.cover,
colorFilter: ColorFilter.mode(
Colors.black, BlendMode.color))),
),
),
Expanded(
flex: 2,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Text("\$ ${items[index].price}"),
Text("${items[index].name}")
],
),
)
],
),
),
);
},
itemCount: items.length,
crossAxisCount: 4,
mainAxisSpacing: 16,
crossAxisSpacing: 16,
staggeredTileBuilder: (int index) {
return new StaggeredTile.count(2, index.isEven ? 4 : 3);
},
),
// child: GridView.builder(
// itemCount:items.length,
// itemBuilder: (BuildContext context, int index) {
// return Container(
// child: Column(
// children: <Widget>[
// Expanded(
// flex: 8,
// child: Container(
// decoration: BoxDecoration(
// image: DecorationImage(
// image: NetworkImage(
// items[index].img
// ),
// fit: BoxFit.cover,
// colorFilter: ColorFilter.mode(Colors.black, BlendMode.color)
// )
// ),
// ),
// ),
// Expanded(
// flex: 2,
// child: Row(
// mainAxisAlignment: MainAxisAlignment.spaceBetween,
// children: <Widget>[
// Text("\$ ${items[index].price}"),
// Text("${items[index].name}")
// ],
// ),
// )
// ],
// ),
// ) ;
// },
// gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
// crossAxisCount: 2,
// childAspectRatio: 0.55,
// crossAxisSpacing: 16,
// mainAxisSpacing: 16
// ),
//
// ),
),
)
],
),
),
);
}
}
class searcher extends SearchDelegate {
@override
List<Widget> buildActions(BuildContext context) {
// TODO: implement buildActions
throw UnimplementedError();
}
@override
Widget buildLeading(BuildContext context) {
// TODO: implement buildLeading
throw UnimplementedError();
}
@override
Widget buildResults(BuildContext context) {
// TODO: implement buildResults
throw UnimplementedError();
}
@override
Widget buildSuggestions(BuildContext context) {
// TODO: implement buildSuggestions
throw UnimplementedError();
}
}
三つ目のページ。
Product Detail Page
detail_page.dart
import 'package:flutter/material.dart';
import 'package:flutter_notebook_4th/ep355_monochrome_shop_app/entered_page.dart';
class ItemDetailPage extends StatelessWidget {
final Wear wear;
ItemDetailPage({this.wear});
@override
Widget build(BuildContext context) {
return Scaffold(
body: SafeArea(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Expanded(
flex: 2,
child: Padding(
padding: EdgeInsets.symmetric(horizontal: 24),
child: Row(
children: <Widget>[
IconButton(
icon: Icon(Icons.clear),
onPressed: () {
Navigator.pop(context);
},
),
Spacer(),
Text(
"${wear.name}",
style: TextStyle(fontSize: 20),
),
Spacer(),
],
),
),
),
Expanded(
flex: 6,
child: Container(
decoration: BoxDecoration(
image: DecorationImage(
image: NetworkImage(wear.img),
fit: BoxFit.cover,
colorFilter:
ColorFilter.mode(Colors.black, BlendMode.color)),
),
),
),
Expanded(
flex: 1,
child: Padding(
padding: const EdgeInsets.only(left: 24),
child: Row(
children: <Widget>[
Container(
margin: EdgeInsets.only(right: 12),
height: 4,
width: 24,
decoration: BoxDecoration(
color: Colors.blueGrey,
),
),
Container(
margin: EdgeInsets.only(right: 12),
height: 4,
width: 24,
decoration: BoxDecoration(
color: Colors.grey,
),
),
Container(
margin: EdgeInsets.only(right: 12),
height: 4,
width: 24,
decoration: BoxDecoration(
color: Colors.grey,
),
),
Container(
margin: EdgeInsets.only(right: 12),
height: 4,
width: 24,
decoration: BoxDecoration(
color: Colors.grey,
),
)
],
),
),
),
Expanded(
flex: 1,
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 24),
child: Text("No matter the occasion girl, get ready to edge\n"
"out your suits collection and be best dressed"),
),
),
Expanded(
flex: 7,
child: Column(
children: <Widget>[
Expanded(
flex: 1,
child: Container(
child: Row(
children: <Widget>[
Expanded(
flex: 10,
child: Container(
padding: EdgeInsets.only(left: 40),
height: double.infinity,
color: Colors.grey.shade200,
child: Align(
alignment: Alignment.centerLeft,
child: Text(
"Detail",
style: TextStyle(fontSize: 20),
)),
),
),
Expanded(
flex: 2,
child: Container(
child: Center(
child: Icon(
Icons.card_giftcard,
color: Colors.grey.shade400,
),
),
),
)
],
),
),
),
Expanded(
flex: 1,
child: Container(
child: Row(
children: <Widget>[
Expanded(
flex: 10,
child: Container(
padding: EdgeInsets.only(left: 80),
height: double.infinity,
color: Colors.grey.shade400,
child: Align(
alignment: Alignment.centerLeft,
child: Text(
"Delivery",
style: TextStyle(fontSize: 20),
)),
),
),
Expanded(
flex: 2,
child: Container(
child: Center(
child: Icon(
Icons.favorite_border,
color: Colors.grey.shade400,
),
),
),
)
],
),
),
),
Expanded(
flex: 1,
child: Container(
child: Row(
children: <Widget>[
Expanded(
flex: 10,
child: Container(
padding: EdgeInsets.only(left: 120),
height: double.infinity,
color: Colors.grey.shade600,
child: Align(
alignment: Alignment.centerLeft,
child: Text(
"Discount",
style: TextStyle(fontSize: 20),
)),
),
),
Expanded(
flex: 2,
child: Container(
child: Center(
child: Icon(
Icons.share,
color: Colors.grey.shade400,
),
),
),
)
],
),
),
),
Expanded(
flex: 1,
child: Container(
child: Row(
children: <Widget>[
Expanded(
flex: 10,
child: Container(
child: Row(
children: <Widget>[
Expanded(
flex: 3,
child: Container(
color: Colors.white,
child: Center(
child: Text(
"\$${wear.price}",
style: TextStyle(
fontSize: 20,
fontWeight: FontWeight.bold,
),
),
),
),
),
Expanded(
flex: 8,
child: Container(
color: Colors.black,
child: Center(
child: Text(
"Add to Cart",
style: TextStyle(
color: Colors.white,
fontSize: 20),
),
),
),
)
],
),
),
),
Expanded(
flex: 2,
child: Container(
child: Center(
child: Icon(
Icons.more_horiz,
color: Colors.grey.shade400,
),
),
),
)
],
),
),
),
Expanded(
flex: 1,
child: Container(),
)
],
),
),
],
),
),
);
}
}
終わりに
今回も読んでくださってありがとうございます。