Menu
CoddyTech

עגלת קניות: הסכום הכולל

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

מסך העגלה זקוק לסכום כולל. הסכום הכולל אינו נתון חדש: הוא נובע מהתוכן שבעגלה. לכן הוא לא נשמר בשום מקום. זהו ספק שעוקב אחר העגלה ומחבר את המחירים באמצעות fold:

final totalProvider = Provider((ref) {
  final cart = ref.watch(cartProvider);
  return cart.fold(0.0, (sum, product) => sum + product.price);
});

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

הציגו אותו מתחת לרשימה. המשבצת bottomNavigationBar של Scaffold מקבלת כל רכיב ומשאירה אותו בתחתית המסך, מתחת לרשימה, גם כשהרשימה נגללת.

challenge icon

אתגר

בינוני

הצג את הסכום הכולל במסך העגלה:

  • הוסף totalProvider שעוקב אחר cartProvider ומחבר את המחירים.
  • במסך העגלה, הצג את Total: $2.75 (עם שתי ספרות אחרי הנקודה העשרונית) בתוך bottomNavigationBar של Scaffold, עם מעט ריווח פנימי.

נסו בעצמכם

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: 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);
    return Scaffold(
      appBar: AppBar(title: const Text('Your cart')),
      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)}'),
                  ),
              ],
            ),
    );
  }
}
quiz iconבחנו את עצמכם

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

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

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