Menu
CoddyTech

Keranjang Belanja: Total

Termasuk bagian Pengelolaan State dalam perjalanan Flutter di Coddy. Pelajaran 25 dari 27.

Layar keranjang memerlukan total. Total bukan data baru: nilainya berasal dari isi keranjang. Jadi, total tidak disimpan di mana pun. Total adalah provider yang mengamati keranjang dan menjumlahkan harganya dengan fold:

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

Karena provider ini mengamati keranjang, total dihitung ulang setiap kali keranjang berubah, dan setiap widget yang mengamati total akan menampilkan jumlah yang baru.

Tampilkan total di bawah list. Slot bottomNavigationBar milik Scaffold menerima widget apa pun dan menempatkannya di bagian bawah layar, di bawah list, bahkan saat list digulir.

challenge icon

Tantangan

Sedang

Tampilkan total di layar keranjang:

  • Tambahkan totalProvider yang memantau cartProvider dan menjumlahkan harga.
  • Di layar keranjang, tampilkan Total: $2.75 (dua angka desimal) di bottomNavigationBar milik Scaffold, dengan sedikit padding.

Coba sendiri

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 iconUji dirimu

Pelajaran ini berisi kuis singkat. Mulai pelajarannya untuk menjawab kuis dan melacak progresmu.

Semua pelajaran di Pengelolaan State

Latihan sendiri: Compiler Flutter online