Menu
CoddyTech

עגלת קניות: התג

חלק מהיחידה ניהול מצב במסלול ה-Flutter של Coddy. שיעור 23 מתוך 27.

חנויות מציגות את העגלה כסמל עם מספר קטן עליו, תג. ל-Flutter יש רכיב מתאים: Badge מצייר את ה-label שלו בבועה אדומה בפינה של ה-child שלו:

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

isLabelVisible מסתיר את הבועה כשהערך שלו הוא false. בעגלה ריקה מוצג הסמל לבדו, וזה פחות בולט מ-0. הערך של cart.isNotEmpty הוא true כאשר יש ברשימה לפחות פריט אחד.

התג עוקב אחר אותו cartProvider שהכותרת עקבה אחריו. כל רכיב יכול לעשות זאת, בכל מקום שבו הוא נמצא.

challenge icon

אתגר

קל

העבירו את הספירה מהכותרת לתג:

  • הכותרת חוזרת להיות Shop.
  • הוסיפו IconButton של עגלת קניות אל actions שבסרגל העליון, ובתוכו Icons.shopping_cart בתוך Badge שמציג את מספר המוצרים.
  • הסתירו את המספר בתג כשהעגלה ריקה.

הכפתור עדיין לא עושה דבר; מסך העגלה יגיע בהמשך.

נסו בעצמכם

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 iconבחנו את עצמכם

השיעור הזה כולל חידון קצר. התחילו את השיעור כדי לענות עליו ולעקוב אחרי ההתקדמות.

כל השיעורים ביחידה ניהול מצב

תרגלו בעצמכם: קומפיילר Flutter אונליין