https://codekodo.tistory.com/88
์ง๋ ์ฃผ์ ์ผ๋ถ ๊ตฌํํ Shop App์ ๊ธฐ๋ฅ์ ์ถ๊ฐํ๋ค.
GridView๋ก ํํํ ์์ดํ ์ ํด๋ฆญํ๋ฉด ํด๋น ์์ดํ ์ ์์ธ ์ ๋ณด๋ฅผ ๋ณด์ฌ์ค๋ค.
import 'package:flutter/material.dart';
import '/providers/products.dart';
import 'package:provider/provider.dart';
class ProductDetailScreen extends StatelessWidget {
static const routeName = '/product-detail';
@override
Widget build(BuildContext context) {
final productId = ModalRoute.of(context).settings.arguments as String;
final loadedProduct = Provider.of<Products>(
context,
listen: false,
).findById(productId); // ํ๋ก๋ฐ์ด๋๊ฐ ์ ๊ณตํ ๋ฐ์ดํฐ๋ฅผ ์์ธ์ค ๊ฐ๋ฅ
return Scaffold(
appBar: AppBar(
title: Text(loadedProduct.title),
),
body: SingleChildScrollView(
child: Column(
children: <Widget>[
Container(
height: 300,
width: double.infinity,
child: Image.network(
loadedProduct.imageUrl,
fit: BoxFit.cover,
),
),
SizedBox(
height: 10,
),
Text(
'${loadedProduct.price}์',
style: TextStyle(
color: Colors.grey,
fontSize: 20,
),
),
SizedBox(
height: 10,
),
Container(
padding : EdgeInsets.symmetric(horizontal: 10),
width : double.infinity,
child: Text(
loadedProduct.description,
textAlign: TextAlign.center,
softWrap: true,
),
),
],
),
));
}
}
pushNamed๋ก ๋๊ฒจ๋ฐ์ ์ธ์๋ค์ Modalroute๋ฅผ ์ด์ฉํ์ฌ ๊ฐ์ ธ์จ๋ค.
์ดํ Product๊ฐ ์ ์ฅ๋ ๋ฆฌ์คํธ์์ ํด๋น ์ํ์ ์ฐพ๊ณ , ์ํ ์ฌ์ง, ์ํ๋ช , ์ํ ๊ฐ๊ฒฉ์ ๋ณด์ฌ์ค๋ค.
๋ค์์ ์ํ ๋ชฉ๋ก์ ๋ณด์ฌ์ฃผ๊ณ ๊ด์ฌ ์ํ์ผ๋ก ์ฒดํฌํ๊ฑฐ๋ ์ฅ๋ฐ๊ตฌ๋์ ๋ด๋ ๊ธฐ๋ฅ์ ์ถ๊ฐํ๋ค.
import 'package:flutter/material.dart';
import '/providers/products.dart';
import '/widgets/app_drawer.dart';
import '/screens/cart_screen.dart';
import '/providers/cart.dart';
import 'package:provider/provider.dart';
import '../widgets/products_grid.dart';
import '../widgets/badge.dart';
enum FilterOptions {
Favorites,
All,
}
class ProductsOverviewScreen extends StatefulWidget {
@override
_ProductsOverviewScreenState createState() => _ProductsOverviewScreenState();
}
class _ProductsOverviewScreenState extends State<ProductsOverviewScreen> {
var _showOnlyFavorites = false;
var _isInit = true;
var _isLoading = false;
@override
void initState() {
// Provider.of<Products>(context).fetchAndSetProducts(); -> context๊ฐ ์๋๋ฐ ์ฐธ๊ณ ํ๋ฏ๋ก ์ค๋ฅ
// Future.delayed(Duration.zero).then((_) {
// Provider.of<Products>(context).fetchAndSetProducts();
// });
super.initState();
}
@override
void didChangeDependencies() {
if (_isInit) {
_isLoading = true;
Provider.of<Products>(context).fetchAndSetProducts().then((_) {
setState(() {
_isLoading = false;
});
});
}
_isInit = false;
super.didChangeDependencies();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('๊ณ ๋ ์ผํ'),
actions: <Widget>[
PopupMenuButton(
onSelected: (FilterOptions selectedValue) {
setState(() {
if (selectedValue == FilterOptions.Favorites) {
_showOnlyFavorites = true;
} else {
_showOnlyFavorites = false;
}
});
},
icon: Icon(
Icons.more_vert,
),
itemBuilder: (_) => [
PopupMenuItem(
child: Text('๊ด์ฌ์ํ๋ง ๋ณด๊ธฐ'),
value: FilterOptions.Favorites,
),
PopupMenuItem(
child: Text('๋ชจ๋ ๋ณด๊ธฐ'),
value: FilterOptions.All,
),
],
),
Consumer<Cart>(
builder: (_, cart, child) => // child๋ build๊ฐ ๋ฐ์ํ์ง ์์
Badge(
child: child as Widget,
value: cart.itemCount.toString(),
color: Colors.red,
),
child: IconButton(
icon: Icon(
Icons.shopping_cart,
),
onPressed: () {
Navigator.of(context).pushNamed(CartScreen.routeName);
},
),
),
],
),
drawer: AppDrawer(),
body: _isLoading
? Center(
child: CircularProgressIndicator(),
)
: ProductsGrid(_showOnlyFavorites),
);
}
}
PopupMenuButton์ ์ด์ฉํ์ฌ ๊ด์ฌ ์ํ ํน์ ๋ชจ๋ ์ํ์ ๋ณผ ์ ์๋๋ก ๋ฉ๋ด ์ ํ์ง๋ฅผ ์ถ๊ฐํ๋ค.
๋ค์์ Consumer๋ฅผ ํตํด Cart Provider์ ์ ๊ทผํ๋๋ฐ Consumer์ child ์์ฑ์ ํตํด ๋ฐ์ดํฐ์ ๋ณ๊ฒฝ์ด ์ผ์ด๋๋ฉด
child๋ก ์ ์ธํ ๋ถ๋ถ๋ง ๊ฐฑ์ ๋๋ค.
drawer๋ ๋ฐ๋ก ๋ง๋ค์ด์ค AppDrawer ํด๋์ค๋ฅผ ๋ฃ์ด์คฌ๋ค.
์ด ๋ถ๋ถ์ ์ข์ธก์ ์ฌ์ด๋๋ฐ๋ฅผ ๋ง๋ค์ด์ฃผ๋ ์์ ฏ ํด๋์ค์ด๋ค.
AppDrawer ํด๋์ค๋ฅผ ์ดํด๋ณด์.
import 'package:flutter/material.dart';
import '/screens/user_product.dart';
import '/screens/orders_screen.dart';
class AppDrawer extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Drawer(
child: Column(
children: <Widget>[
AppBar(
title: Text("์๋
ํ์ธ์, ๊ณ ๋ํ๋"),
automaticallyImplyLeading: false,
),
Divider(),
ListTile(
leading: Icon(Icons.shop),
title: Text('์ํ ํ์ธ'),
onTap : () {
Navigator.of(context).pushReplacementNamed('/');
}
),
Divider(),
ListTile(
leading: Icon(Icons.shopping_cart),
title: Text('์ฃผ๋ฌธ ๋ด์ญ'),
onTap : () {
Navigator.of(context).pushReplacementNamed(OrdersScreen.routeName);
}
),
Divider(),
ListTile(
leading: Icon(Icons.edit),
title: Text('์ํ ๊ด๋ฆฌ'),
onTap : () {
Navigator.of(context).pushReplacementNamed(UserProductsScreen.routeName);
}
),
],
),
);
}
}
ListTile๋ก ์ฌ์ด๋๋ฐ๋ก ํ์ํ ์์๋ค์ ๋ํ๋๋ค.
์ดํ Divider๋ก ListTile ์ฌ์ด์ ๊ตฌ๋ถ์ ์ด ๋ค์ด๊ฐ๋๋ก ๊ตฌํํ๋ค.
์์ค์ฝ๋๋ ์๋ ๋งํฌ๋ฅผ ํตํด ์ ์ํ๋ฉด ํ์ธํ ์ ์๋ค.
https://github.com/k906506/2021-Summer-Flutter-Study/tree/master/myfourthflutterapp
'โน๏ธ ๋ผ์ดํ > 2021 ์ฌ๋ฆ๋ฐฉํ ๋ชจ๊ฐ์ฝ(๊ฐ์ธ)' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[์ฝ๋ ํ๊ตฌ๋ง 2] 6์ฃผ์ฐจ - Flutter : Shop App 3 (0) | 2021.08.10 |
---|---|
[์ฝ๋ ํ๊ตฌ๋ง 2] 4์ฃผ์ฐจ - Flutter : Shop App 1 (0) | 2021.07.28 |
[์ฝ๋ ํ๊ตฌ๋ง 2] 3์ฃผ์ฐจ - Flutter : Personal Expense App (2) | 2021.07.22 |
[์ฝ๋ ํ๊ตฌ๋ง 2] 2์ฃผ์ฐจ - Flutter : Personal Expense App (0) | 2021.07.15 |
[์ฝ๋ ํ๊ตฌ๋ง 2] 1์ฃผ์ฐจ - Flutter : Quiz App (0) | 2021.07.07 |