Warenkorb: Artikel entfernen
Teil des Abschnitts State Management der Flutter-Journey von Coddy. Lektion 26 von 27.
Wer versehentlich das Falsche hinzufügt, braucht eine Möglichkeit, es wieder zu entfernen: eine Löschen-Schaltfläche in jeder Warenkorbzeile.
Im Warenkorb kann dasselbe Produkt zweimal liegen, deshalb wird nach Position und nicht nach Produkt entfernt. Die Regel von vorhin gilt weiterhin: Ändere state niemals direkt. Erstelle eine Kopie, ändere die Kopie und setze sie als neuen Zustand:
void removeAt(int index) {
final copy = [...state];
copy.removeAt(index);
state = copy;
}Um die Position jeder Zeile zu kennen, durchlaufe die Liste mit einem Index: for (var i = 0; i < cart.length; i++), und verwende cart[i] für das Produkt in dieser Zeile.
Lösche einen Artikel und beobachte, wie der Rest folgt: die Liste, die Gesamtsumme und, zurück im Shop, das Symbol. Sie alle beobachten denselben Warenkorb.
Aufgabe
SchwerAuf dem Warenkorbbildschirm:
- Füge
Carteine MethoderemoveAt(int index)hinzu, die eine neue Liste ohne dieses Element festlegt. - Verschiebe den Preis jeder Zeile nach
subtitleund machetrailingzu einemIconButtonmitIcons.delete, der die jeweilige Zeile entfernt.
Probier es selbst
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
class Product {
const Product(this.name, this.price);
final String name;
final double price;
}
const products = [
Product('Apple', 0.5),
Product('Bread', 2.25),
Product('Cheese', 4),
Product('Milk', 1.2),
];
class Cart extends Notifier<List<Product>> {
@override
List<Product> build() => [];
void add(Product product) {
state = [...state, product];
}
}
final cartProvider = NotifierProvider<Cart, List<Product>>(Cart.new);
final totalProvider = Provider((ref) {
final cart = ref.watch(cartProvider);
return cart.fold(0.0, (sum, product) => sum + product.price);
});
void main() {
runApp(const ProviderScope(child: MyApp()));
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return const MaterialApp(
debugShowCheckedModeBanner: false,
home: ShopPage(),
);
}
}
class ShopPage extends ConsumerWidget {
const ShopPage({super.key});
@override
Widget build(BuildContext context, WidgetRef ref) {
final cart = ref.watch(cartProvider);
return Scaffold(
appBar: AppBar(
title: const Text('Shop'),
actions: [
IconButton(
icon: Badge(
label: Text('${cart.length}'),
isLabelVisible: cart.isNotEmpty,
child: const Icon(Icons.shopping_cart),
),
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => const CartScreen()),
);
},
),
],
),
body: ListView(
children: [
for (final product in products)
ListTile(
title: Text(product.name),
subtitle: Text('\$${product.price.toStringAsFixed(2)}'),
trailing: IconButton(
icon: const Icon(Icons.add_shopping_cart),
onPressed: () {
ref.read(cartProvider.notifier).add(product);
},
),
),
],
),
);
}
}
class CartScreen extends ConsumerWidget {
const CartScreen({super.key});
@override
Widget build(BuildContext context, WidgetRef ref) {
final cart = ref.watch(cartProvider);
final total = ref.watch(totalProvider);
return Scaffold(
appBar: AppBar(title: const Text('Your cart')),
bottomNavigationBar: Padding(
padding: const EdgeInsets.all(24),
child: Text(
'Total: \$${total.toStringAsFixed(2)}',
style: const TextStyle(fontSize: 24, fontWeight: FontWeight.bold),
),
),
body: cart.isEmpty
? const Center(child: Text('Your cart is empty'))
: ListView(
children: [
for (final product in cart)
ListTile(
title: Text(product.name),
trailing: Text('\$${product.price.toStringAsFixed(2)}'),
),
],
),
);
}
}
Diese Lektion enthält ein kurzes Quiz. Starte die Lektion, um es zu beantworten und deinen Fortschritt zu speichern.
Alle Lektionen in State Management
2Dart für Modelle
Methoden in Ihren KlassenGetter in Ihren KlassenEin Feld privat haltenEine Liste mit fold aufsummieren5Projekt: Warenkorb
Warenkorb: In den Warenkorb legenWarenkorb: Das BadgeÜbe selbstständig: Online-Flutter-Compiler