Skip to content

Instantly share code, notes, and snippets.

@hanskokx
Last active November 23, 2023 17:45
Show Gist options
  • Save hanskokx/7790b9d071a1a3e1bedfdc028e569313 to your computer and use it in GitHub Desktop.
Save hanskokx/7790b9d071a1a3e1bedfdc028e569313 to your computer and use it in GitHub Desktop.
Flutter Provider example
import 'dart:collection';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
void main() {
runApp(
ChangeNotifierProvider(
create: (context) => ShoppingCartProvider(),
child: const MyApp(),
),
);
}
const List<Item> inventory = [
Item(name: "Shirt", cost: 12.99),
Item(name: "Shoes", cost: 120.00),
Item(name: "Pants", cost: 63.74),
Item(name: "Hat", cost: 8.23),
];
class Inventory extends StatelessWidget {
const Inventory({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Consumer<ShoppingCartProvider>(
builder:
(BuildContext context, ShoppingCartProvider cart, Widget? child) {
return ListView(
shrinkWrap: true,
physics: const ClampingScrollPhysics(),
children: [
Text(
'Inventory',
style: Theme.of(context).textTheme.displayMedium,
),
ListView.builder(
shrinkWrap: true,
physics: const ClampingScrollPhysics(),
itemCount: inventory.length,
itemBuilder: (BuildContext context, int i) => Card(
child: ListTile(
title: Text(inventory[i].name),
subtitle: Text('\$${inventory[i].cost.toStringAsFixed(2)}'),
trailing: IconButton(
icon: const Icon(Icons.add_shopping_cart),
onPressed: () => cart.add(inventory[i]),
),
),
),
),
],
);
},
);
}
}
class Item {
final double cost;
final String name;
const Item({
required this.cost,
required this.name,
});
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: Padding(
padding: const EdgeInsets.all(8.0),
child: ListView(
children: const [
Inventory(),
ShoppingCart(),
],
),
),
),
);
}
}
class ShoppingCart extends StatelessWidget {
const ShoppingCart({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Consumer<ShoppingCartProvider>(
builder:
(BuildContext context, ShoppingCartProvider cart, Widget? child) =>
ListView(
shrinkWrap: true,
physics: const ClampingScrollPhysics(),
children: [
Text(
'Shopping Cart',
style: Theme.of(context).textTheme.displayMedium,
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
Text('Items in Cart: ${cart.itemsInCart.length}'),
Text('Total Cost: \$${cart.totalCost.toStringAsFixed(2)}'),
OutlinedButton.icon(
label: const Text('Clear cart'),
icon: const Icon(Icons.remove_shopping_cart),
onPressed: () =>
Provider.of<ShoppingCartProvider>(context, listen: false)
.emptyCart(),
),
],
),
ListView.builder(
shrinkWrap: true,
physics: const ClampingScrollPhysics(),
itemCount: cart.uniqueItems.length,
itemBuilder: (context, i) => Card(
child: ListTile(
leading: Text(
'${cart.itemsInCart.where((element) => element == cart.uniqueItems[i]).length} ×',
),
title: Text(
cart.itemsInCart
.firstWhere((element) => element == cart.uniqueItems[i])
.name,
),
subtitle:
Text('\$${cart.itemsInCart[i].cost.toStringAsFixed(2)}'),
),
),
),
],
),
);
}
}
class ShoppingCartProvider extends ChangeNotifier {
final List<Item> _itemsInCart = [];
UnmodifiableListView<Item> get itemsInCart =>
UnmodifiableListView(_itemsInCart);
double get totalCost {
double price = 0;
for (Item item in _itemsInCart) {
price += item.cost;
}
return price;
}
List<Item> get uniqueItems {
final List<Item> unique = [];
for (Item item in _itemsInCart) {
if (!unique.contains(item)) {
unique.add(item);
}
}
return unique;
}
void add(Item item) {
_itemsInCart.add(item);
notifyListeners();
}
void emptyCart() {
_itemsInCart.clear();
notifyListeners();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment