Flutter中PointsPage的points变量无法传递至CartPage求助
解决Flutter中Points变量跨页面及Model共享问题
问题描述
我尝试了多种方法传递points变量,但无法在另一个类中使用。想将PointsPage中的points变量在CartPage中使用,并且CartPage对应的CartModel也需要使用该变量来实现“购买”功能,但目前无法做到。
现有代码
CartPage
class CartPage extends StatefulWidget { _CartPagestate createState() => _CartPagestate(); } class _CartPagestate extends State<CartPage> { @override Widget build(BuildContext context) { // some code... } }
PointsPage
class points extends StatefulWidget { _pointsState createState() => _pointsState(); } class _pointsState extends State<cubox> { int points = 0; @override void initState() { super.initState(); _loadPoints(); } _loadPunti() async { SharedPreferences prefs = await SharedPreferences.getInstance(); setState(() { punti = (prefs.getInt('points') ?? 0); }); } _savePunti() async { SharedPreferences prefs = await SharedPreferences.getInstance(); prefs.setInt('points', points); } @override Widget build(BuildContext context) { // some code... } }
CartModel
class CartModel extends ChangeNotifier { // list of items on sale final List _shopItems = const [ // [ itemName, itemPrice, imagePath, color ] ["Avocado", "4", "assets/images/avocado.png", Colors.green], ["Banana", "2", "assets/images/banana.png", Colors.yellow], ["chicken", "12", "assets/images/chicken.png", Colors.brown], ["water", "1", "assets/images/water.png", Colors.blue], ["apple", "3", "assets/images/mela.png", Colors.red], ["chocolate", "3", "assets/images/broccoli.png", Colors.brown], ]; final List _other = const [ ["Avocado", "14000", "assets/images/avocado.png", Colors.orange], ["Banana", "2", "assets/images/banana.png", Colors.blueGrey], ["chicken", "12", "assets/images/chicken.png", Colors.red], ["water", "1", "assets/images/water.png", Colors.blue], ]; // list of cart items final List _cartItems = []; get other => _other; get cartItems => _cartItems; get shopItems => _shopItems; // add item to cart void addItemToCart(int index) { _cartItems.add(_shopItems[index]); notifyListeners(); } // remove item from cart void removeItemFromCart(int index) { _cartItems.removeAt(index); notifyListeners(); } // calculate total price String calculateTotal() { double totalPrice = 0; for (int i = 0; i < cartItems.length; i++) { totalPrice += double.parse(cartItems[i][1].toString()); } return totalPrice.toStringAsFixed(2); } }
解决方案
方案1:基于Provider的状态管理(推荐)
既然你已经用到了ChangeNotifier,直接扩展CartModel来统一管理points状态,实现跨页面和Model的共享。
1. 修改CartModel,集成points管理
class CartModel extends ChangeNotifier { // 新增points状态 int _points = 0; int get points => _points; // 加载本地存储的points Future<void> loadPoints() async { SharedPreferences prefs = await SharedPreferences.getInstance(); _points = prefs.getInt('points') ?? 0; notifyListeners(); } // 保存points到本地 Future<void> savePoints() async { SharedPreferences prefs = await SharedPreferences.getInstance(); prefs.setInt('points', _points); } // 购买逻辑:扣除对应积分 bool purchaseItems() { double total = double.parse(calculateTotal()); if (_points >= total) { _points -= total.toInt(); _cartItems.clear(); // 购买后清空购物车 savePoints(); notifyListeners(); return true; } return false; // 积分不足 } // 原有代码保留 final List _shopItems = const [ ["Avocado", "4", "assets/images/avocado.png", Colors.green], ["Banana", "2", "assets/images/banana.png", Colors.yellow], ["chicken", "12", "assets/images/chicken.png", Colors.brown], ["water", "1", "assets/images/water.png", Colors.blue], ["apple", "3", "assets/images/mela.png", Colors.red], ["chocolate", "3", "assets/images/broccoli.png", Colors.brown], ]; final List _other = const [ ["Avocado", "14000", "assets/images/avocado.png", Colors.orange], ["Banana", "2", "assets/images/banana.png", Colors.blueGrey], ["chicken", "12", "assets/images/chicken.png", Colors.red], ["water", "1", "assets/images/water.png", Colors.blue], ]; final List _cartItems = []; get other => _other; get cartItems => _cartItems; get shopItems => _shopItems; void addItemToCart(int index) { _cartItems.add(_shopItems[index]); notifyListeners(); } void removeItemFromCart(int index) { _cartItems.removeAt(index); notifyListeners(); } String calculateTotal() { double totalPrice = 0; for (int i = 0; i < cartItems.length; i++) { totalPrice += double.parse(cartItems[i][1].toString()); } return totalPrice.toStringAsFixed(2); } }
2. 修改PointsPage,通过Provider获取和更新points
// 修正类名符合Dart规范(首字母大写) class PointsPage extends StatefulWidget { const PointsPage({super.key}); @override _PointsPageState createState() => _PointsPageState(); } class _PointsPageState extends State<PointsPage> { late CartModel _cartModel; @override void initState() { super.initState(); _cartModel = Provider.of<CartModel>(context, listen: false); _cartModel.loadPoints(); } // 示例:增加积分的方法 void _addPoints(int amount) { _cartModel._points += amount; _cartModel.savePoints(); _cartModel.notifyListeners(); } @override Widget build(BuildContext context) { return Scaffold( body: Center( child: Consumer<CartModel>( builder: (context, model, child) { return Text("当前积分:${model.points}"); }, ), ), ); } }
3. 修改CartPage,实现购买功能
class CartPage extends StatefulWidget { const CartPage({super.key}); @override _CartPageState createState() => _CartPageState(); } class _CartPageState extends State<CartPage> { late CartModel _cartModel; @override void initState() { super.initState(); _cartModel = Provider.of<CartModel>(context, listen: false); _cartModel.loadPoints(); } void _handlePurchase() { bool success = _cartModel.purchaseItems(); if (success) { ScaffoldMessenger.of(context).showSnackBar( const SnackBar(content: Text("购买成功!")), ); } else { ScaffoldMessenger.of(context).showSnackBar( const SnackBar(content: Text("积分不足,无法购买")), ); } } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: const Text("购物车")), body: Consumer<CartModel>( builder: (context, model, child) { return Column( children: [ Expanded( child: ListView.builder( itemCount: model.cartItems.length, itemBuilder: (context, index) { return ListTile( title: Text(model.cartItems[index][0]), subtitle: Text("价格:${model.cartItems[index][1]}"), trailing: IconButton( icon: const Icon(Icons.remove), onPressed: () => model.removeItemFromCart(index), ), ); }, ), ), Padding( padding: const EdgeInsets.all(16.0), child: Column( children: [ Text("总价:${model.calculateTotal()} 积分"), Text("当前积分:${model.points}"), ElevatedButton( onPressed: _handlePurchase, child: const Text("确认购买"), ), ], ), ), ], ); }, ), ); } }
4. 全局注册Provider
在main.dart中用ChangeNotifierProvider包裹根组件,确保整个App能访问CartModel:
void main() { runApp( ChangeNotifierProvider( create: (context) => CartModel(), child: const MyApp(), ), ); }
方案2:构造函数传值(适合简单场景)
如果只是单次跳转传递points,可在跳转时传入参数:
// 在PointsPage中跳转 Navigator.push( context, MaterialPageRoute( builder: (context) => CartPage(points: _cartModel.points), ), );
修改CartPage接收参数:
class CartPage extends StatefulWidget { final int points; const CartPage({super.key, required this.points}); @override _CartPageState createState() => _CartPageState(); } class _CartPageState extends State<CartPage> { @override Widget build(BuildContext context) { return Text("当前积分:${widget.points}"); } }
注:此方法无法实时同步points变化,也无法在CartModel中直接使用,仅适合简单场景。
内容的提问来源于stack exchange,提问作者sams
相关产品推荐
相关产品推荐

