Menu
CoddyTech

Koszyk zakupowy: Odznaka

Część sekcji Zarządzanie stanem ścieżki Flutter w Coddy. Lekcja 23 z 27.

Sklepy pokazują koszyk jako ikonę z małą liczbą na niej — znaczek. Flutter ma do tego widżet: Badge wyświetla swoją label w czerwonym dymku w rogu swojego child:

IconButton(
  icon: Badge(
    label: Text('${cart.length}'),
    isLabelVisible: cart.isNotEmpty,
    child: const Icon(Icons.shopping_cart),
  ),
  onPressed: () {},
)

isLabelVisible ukrywa dymek, gdy ma wartość false. Pusty koszyk pokazuje samą ikonę, co wygląda spokojniej niż 0. cart.isNotEmpty ma wartość true, gdy lista zawiera co najmniej jeden element.

Znaczek obserwuje ten sam cartProvider, co wcześniej tytuł. Może to robić dowolny widżet, niezależnie od tego, gdzie się znajduje.

challenge icon

Wyzwanie

Łatwy

Przenieś liczbę z tytułu do plakietki:

  • Tytuł wraca do Shop.
  • Dodaj przycisk koszyka IconButton do actions na górnym pasku, z Icons.shopping_cart wewnątrz Badge, który pokazuje liczbę produktów.
  • Ukryj liczbę na plakietce, gdy koszyk jest pusty.

Przycisk jeszcze nic nie robi; w następnej kolejności zajmiemy się ekranem koszyka.

Spróbuj swoich sił

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);

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: Text('Shop (${cart.length})')),
      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);
                },
              ),
            ),
        ],
      ),
    );
  }
}
quiz iconSprawdź się

Ta lekcja zawiera krótki quiz. Zacznij lekcję, żeby na niego odpowiedzieć i śledzić swoje postępy.

Wszystkie lekcje w sekcji Zarządzanie stanem

Poćwicz samodzielnie: Kompilator Flutter online