Skip to content

Instantly share code, notes, and snippets.

@luizjacomn
Last active January 10, 2020 20:01
Show Gist options
  • Save luizjacomn/9a166e744ec4c318ee79c89b1621abf2 to your computer and use it in GitHub Desktop.
Save luizjacomn/9a166e744ec4c318ee79c89b1621abf2 to your computer and use it in GitHub Desktop.
Protótipo de tela de carrinho de compras
import 'package:flutter/material.dart';
final pc = Colors.blueGrey.shade900;
final sc = Colors.blueGrey.shade800;
final bc = Colors.blueGrey;
final wc = Colors.white;
final ac = Colors.amber;
final tc = Colors.transparent;
final gc = Colors.green;
final rc = Colors.red;
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Carrinho',
debugShowCheckedModeBanner: false,
home: MyHomePage(title: 'Carrinho'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
final cart = Cart();
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: pc,
appBar: AppBar(
backgroundColor: pc,
title: Row(
crossAxisAlignment: CrossAxisAlignment.end,
children: <Widget>[
Icon(Icons.shopping_basket, color: ac),
SizedBox(width: 8),
Text(
widget.title,
style: TextStyle(color: ac),
),
],
),
actions: <Widget>[
Visibility(
visible: cart.isNotEmpty,
child: IconButton(
icon: Icon(
Icons.clear_all,
),
onPressed: () {
setState(() {
cart.removeAll();
});
},
),
),
],
),
body: cart.isEmpty
? Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Icon(
Icons.sentiment_very_dissatisfied,
color: bc,
size: 72,
),
SizedBox(height: 16),
Text(
'Seu carrinho está vazio!'.toUpperCase(),
style: TextStyle(color: bc, fontSize: 16),
),
SizedBox(height: 4),
GestureDetector(
child: Text(
'Adicione itens agora mesmo'.toUpperCase(),
style: TextStyle(color: ac, fontSize: 12),
),
onTap: () {
setState(() {
cart.addAll();
});
},
),
],
),
)
: Column(
children: <Widget>[
Center(
child: Padding(
padding:
const EdgeInsets.symmetric(vertical: 16),
child: Container(
padding: const EdgeInsets.symmetric(vertical: 8),
color: gc,
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Container(
padding: const EdgeInsets.symmetric(
horizontal: 8,
vertical: 4,
),
decoration: BoxDecoration(
color: wc,
borderRadius: BorderRadius.all(
Radius.circular(4),
),
),
child: Text(
'${cart.size}',
style: TextStyle(color: gc),
),
),
SizedBox(width: 8),
Text(
'ITENS NO CARRINHO',
style: TextStyle(
color: wc,
),
),
],
),
),
),
),
Expanded(
child: ListView.separated(
itemCount: cart.size,
separatorBuilder: (_, __) => Divider(height: 0),
itemBuilder: (context, index) {
final item = cart.itens[index];
return Opacity(
opacity: item.disponivel ? 1 : 0.5,
child: item.disponivel
? Dismissible(
key: Key(UniqueKey().toString()),
onDismissed: (direction) {
if (direction ==
DismissDirection.endToStart) {
Scaffold.of(context).showSnackBar(
SnackBar(
content: Text('${item.nome} removida'),
duration: Duration(seconds: 1),
),
);
} else {
Scaffold.of(context).showSnackBar(
SnackBar(
content:
Text('${item.nome} para edição'),
duration: Duration(seconds: 1),
),
);
}
setState(() {
cart.remove(item);
});
},
background: Container(
decoration: BoxDecoration(color: gc),
padding: EdgeInsets.all(5.0),
child: Row(
children: <Widget>[
Padding(
padding:
const EdgeInsets.only(left: 20.0),
child: Text('EDITAR',
style:
TextStyle(color: Colors.white)),
),
],
),
),
secondaryBackground: Container(
decoration: BoxDecoration(color: rc),
padding: EdgeInsets.all(5.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.end,
children: <Widget>[
Padding(
padding:
const EdgeInsets.only(right: 20.0),
child: Text('REMOVER',
style:
TextStyle(color: Colors.white)),
),
],
),
),
child: ItemTile(item: item),
)
: ItemTile(item: item),
);
},
),
),
Padding(
padding:
const EdgeInsets.symmetric(horizontal: 8, vertical: 4),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Text(
'ENTREGA',
style: TextStyle(
color: wc,
),
),
Text(
'R\$ ${cart.ship.toStringAsFixed(2)}',
style: TextStyle(
color: rc,
),
),
],
),
),
Padding(
padding:
const EdgeInsets.symmetric(horizontal: 8, vertical: 4),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Text(
'DESCONTO (${cart.discountPercent})',
style: TextStyle(
color: wc,
),
),
Text(
'- R\$ ${cart.discountValue.toStringAsFixed(2)}',
style: TextStyle(
color: gc,
),
),
],
),
),
Padding(
padding:
const EdgeInsets.symmetric(horizontal: 8, vertical: 4),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Text(
'TOTAL',
style: TextStyle(
color: ac,
),
),
Text(
'R\$ ${cart.totalCart.toStringAsFixed(2)}',
style: TextStyle(
color: ac,
),
),
],
),
),
Padding(
padding:
const EdgeInsets.symmetric(horizontal: 8, vertical: 16),
child: SizedBox(
width: double.infinity,
child: RaisedButton(
color: ac,
child: Text(
'FECHAR PEDIDO',
style: TextStyle(
color: pc,
),
),
onPressed: () {},
),
),
),
],
),
);
}
}
class ItemTile extends StatelessWidget {
final Item item;
ItemTile({Key key, this.item}) : super(key: key);
@override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.symmetric(horizontal: 8),
child: Card(
color: sc,
child: ListTile(
leading: CircleAvatar(
backgroundColor: tc,
child: Image.network(item.img),
),
title: Padding(
padding: const EdgeInsets.only(bottom: 16),
child: Text(
item.nome,
style: TextStyle(
color: wc,
),
),
),
subtitle: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(
'${item.qtd} x R\$ ${item.preco.toStringAsFixed(2)}',
style: TextStyle(
color: wc,
),
),
Text(
item.disponivel ? 'Disponível' : 'Esgotado',
style: TextStyle(
color: item.disponivel ? gc : rc,
),
),
],
),
trailing: Text(
'R\$ ${item.total.toStringAsFixed(2)}',
style: TextStyle(
color: ac,
),
),
),
),
);
}
}
class Cart {
List<Item> itens = [];
void remove(Item item) => itens.remove(item);
void removeAll() => itens.clear();
void addAll() {
itens = [
Item(
nome: 'Magnífica',
qtd: 1,
preco: 11,
img:
'https://www.ambev.com.br/conteudo/uploads/2019/03/magnifica_600ml.png',
estoque: 0,
),
Item(
nome: 'Lake Side',
qtd: 2,
preco: 12,
img:
'https://superprix.vteximg.com.br/arquivos/ids/177258-600-600/cerveja-lake-side.png?v=636595054012930000',
estoque: 3,
),
Item(
nome: 'Petra',
qtd: 3,
preco: 13,
img:
'https://superprix.vteximg.com.br/arquivos/ids/179107-600-600/Cerveja-Petra-Origem-Puro-Malte-355ml-Ln-815250.png?v=636969966571500000',
estoque: 3,
),
Item(
nome: 'Estrella Galicia',
qtd: 4,
preco: 14,
img:
'https://www.emporiofreicaneca.com.br/wp-content/uploads/2019/09/estrella-galicia-600ml-298x600.png',
estoque: 10,
),
];
}
int get size => itens.length;
double get totalCart => itens
.map((item) => item.total)
.fold(0, (prev, current) => prev + current);
double get ship => 9.99;
double get discount => 0.1;
String get discountPercent => '${discount * 100}%';
double get discountValue => totalCart * discount;
bool get isEmpty => itens.isEmpty;
bool get isNotEmpty => !isEmpty;
}
class Item {
String nome;
int qtd;
double preco;
String img;
int estoque;
Item({this.nome, this.qtd, this.preco, this.img, this.estoque});
double get total => this.qtd * this.preco;
bool get disponivel => estoque >= qtd;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment