Alışveriş Sepeti: Ürünleri Kaldırma
Coddy'nin Flutter Journey'sinin Durum Yönetimi bölümünün bir parçası. Ders 26 / 27.
Yanlış ürünü ekleyen bir müşterinin geri alabilmesi gerekir: sepetteki her satıra bir silme düğmesi ekleyin.
Sepette aynı üründen iki tane bulunabilir; bu yüzden ürüne göre değil, konumuna göre kaldırın. Önceki kural hâlâ geçerli: state değerini yerinde asla değiştirmeyin. Bir kopyasını oluşturun, kopyayı değiştirin ve yeni durum olarak ayarlayın:
void removeAt(int index) {
final copy = [...state];
copy.removeAt(index);
state = copy;
}Her satırın konumunu öğrenmek için bir indeksle döngü kurun: for (var i = 0; i < cart.length; i++) ve o satırdaki ürün için cart[i] ifadesini kullanın.
Bir öğeyi silin ve geri kalanların da buna göre değiştiğini görün: liste, toplam tutar ve mağazaya dönünce rozet. Hepsi aynı sepeti izler.
Görev
ZorSepet ekranında:
- O öğe olmadan yeni bir liste ayarlayan bir
removeAt(int index)yönteminiCartsınıfına ekleyin. - Her satırın fiyatını
subtitlealanına taşıyın vetrailingöğesini o satırı kaldıranIcons.deleteiçeren birIconButtonyapın.
Kendin dene
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)}'),
),
],
),
);
}
}
Bu ders kısa bir quiz içerir. Soruları yanıtlamak ve ilerlemeni kaydetmek için derse başla.
Durum Yönetimi bölümündeki tüm dersler
2Modeller için Dart
Sınıflarınızda MetotlarSınıflarınızda Getter'larBir Alanı Gizli Tutunfold ile Bir Listeyi Toplayın5Proje: Alışveriş Sepeti
Alışveriş Sepeti: Sepete EklemeAlışveriş Sepeti: RozetKendi başına pratik yap: Online Flutter derleyicisi