未选商品时触发Bad state: no element错误,需显示空购物车图片
解决空购物车时的Bad State错误并显示空购物车图片
错误原因
当用户未选择任何商品时,_products是空Map,调用reduce方法时,空列表会抛出Bad state: no element错误——因为reduce需要至少一个元素才能执行累加操作。
步骤1:修复总价计算的空值问题
修改total的getter方法,先判断子项列表是否为空,为空则返回0.0,避免报错:
get products => _products; get subtotal => _products.entries.map((product) => product.key.price * product.value).toList(); get total { final subtotals = _products.entries.map((entry) => entry.key.price * entry.value).toList(); // 空列表时返回0,避免reduce报错 return subtotals.isEmpty ? 0.0 : subtotals.reduce((value, element) => value + element); }
步骤2:在UI中判断购物车状态,显示对应内容
在页面build方法中,通过判断_products是否为空,切换显示空购物车图片或正常购物车内容:
@override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: const Text('购物车')), body: _products.isEmpty ? // 空购物车时显示图片 Center( child: Image.asset( 'assets/empty_cart.png', // 替换为你的空购物车图片路径 width: 200, height: 200, ), ) : // 有商品时显示列表和总价 Column( children: [ Expanded( child: ListView.builder( itemCount: _products.entries.length, itemBuilder: (context, index) { final entry = _products.entries.elementAt(index); return ListTile( leading: Image.network(entry.key.imageUrl), title: Text(entry.key.name), subtitle: Text('单价: \$${entry.key.price} × 数量: ${entry.value}'), trailing: Text('小计: \$${(entry.key.price * entry.value).toStringAsFixed(2)}'), ); }, ), ), Padding( padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8), child: Align( alignment: Alignment.centerRight, child: Text( '总价: \$${total.toStringAsFixed(2)}', style: const TextStyle(fontSize: 18, fontWeight: FontWeight.bold), ), ), ), ], ), ); }
额外提示
- 确保
_products是Map<Product, int>类型,初始值为{}(空Map) - 如果使用网络图片作为空购物车图标,替换
Image.asset为Image.network并传入图片URL
内容的提问来源于stack exchange,提问作者Kabakebo
相关产品推荐
相关产品推荐

