You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.28 02:50:20