Корзина покупок: экран корзины
Часть раздела Управление состоянием путешествия по Flutter на Coddy. Урок 24 из 27.
Второй экран показывает содержимое корзины. Это ConsumerWidget, который наблюдает за тем же cartProvider, поэтому ему ничего не нужно передавать: откройте его, и он сам прочитает содержимое корзины.
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: ...,
);
}
}Помните провайдер, который находился вокруг home и был недоступен с открытого экрана? Здесь такого не произойдёт: ProviderScope оборачивает всё приложение, поэтому каждый экран может обращаться к любому провайдеру.
Пустой список на экране выглядит как ошибка, поэтому вместо него покажите текст: cart.isEmpty ? ... : ... выбирает один из двух вариантов.
Задание
СреднеСоздай экран корзины:
- Добавь
CartScreenConsumerWidgetс заголовкомYour cart. - Для каждого товара в корзине отображается
ListTileс названием, а цена указывается вtrailing. - Если корзина пуста, вместо этого отображается
Your cart is empty. - При нажатии на значок корзины в верхней панели магазина он открывается.
Попробуйте сами
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: () {},
),
],
),
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);
},
),
),
],
),
);
}
}
В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.
Все уроки раздела Управление состоянием
2Dart для моделей
Методы ваших классовГеттеры в ваших классахСделайте поле приватнымСуммирование списка с помощью fold5Проект: корзина покупок
Корзина покупок: добавить в корзинуКорзина покупок: значокПотренируйтесь самостоятельно: Онлайн-компилятор Flutter