Flutter在购物场景中BLoC的应用
介绍BLoC的应用场景
一直在思考如何更加详细的介绍。
现在提供一个完整的购物场景 BLoC 示例,包括:
模型:Product
事件:AddProduct、RemoveProduct
状态:CartState 记录购物项和总价
BLoC:CartBloc 实现增删逻辑
界面:ShopPage 展示商品列表和购物车信息
下面的这段代码应该能完整的说明这个问题
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';// 模型
class Product {final int id;final String name;final double price;Product({required this.id, required this.name, required this.price});
}// 事件定义
abstract class CartEvent {}
class AddProduct extends CartEvent {final Product product;AddProduct(this.product);
}
class RemoveProduct extends CartEvent {final Product product;RemoveProduct(this.product);
}// 状态定义
class CartState {final List<Product> items;final double total;CartState({required this.items}) : total = items.fold(0, (sum, p) => sum + p.price);
}// BLoC 实现
class CartBloc extends Bloc<CartEvent, CartState> {CartBloc() : super(CartState(items: [])) {on<AddProduct>((event, emit) {final updated = List<Product>.from(state.items)..add(event.product);emit(CartState(items: updated));});on<RemoveProduct>((event, emit) {final updated = List<Product>.from(state.items)..remove(event.product);emit(CartState(items: updated));});}
}// UI 示例
void main() {runApp(const MyApp());
}class MyApp extends StatelessWidget {const MyApp({super.key});@overrideWidget build(BuildContext context) {return MaterialApp(home: BlocProvider(create: (_) => CartBloc(),child: const ShopPage(),),);}
}class ShopPage extends StatelessWidget {const ShopPage({super.key});final sampleProducts = const [Product(id: 1, name: 'T-Shirt', price: 29.99),Product(id: 2, name: 'Jeans', price: 59.99),Product(id: 3, name: 'Sneakers', price: 89.99),];@overrideWidget build(BuildContext context) {final cartBloc = context.read<CartBloc>();return Scaffold(appBar: AppBar(title: const Text('Shop')),body: Column(children: [Expanded(child: ListView.builder(itemCount: sampleProducts.length,itemBuilder: (context, index) {final product = sampleProducts[index];return ListTile(title: Text(product.name),subtitle: Text("\$${product.price}"),trailing: IconButton(icon: const Icon(Icons.add_shopping_cart),onPressed: () => cartBloc.add(AddProduct(product)),),);},),),const Divider(),BlocBuilder<CartBloc, CartState>(builder: (context, state) {return Padding(padding: const EdgeInsets.all(16.0),child: Column(children: [Text('Items in Cart: ${state.items.length}'),Text('Total: \$${state.total.toStringAsFixed(2)}'),ElevatedButton(onPressed: state.items.isEmpty ? null : () {// 结算逻辑ScaffoldMessenger.of(context).showSnackBar(const SnackBar(content: Text('Proceed to checkout')),);},child: const Text('Checkout'),),],),);},),],),);}
}