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

Flutter底部导航栏页面数据传递及参数缺失报错解决

解决Flutter中Cart页面的构造函数参数错误及购物车数据共享问题

你遇到的1 positional argument(s) expected, but 0 found错误,根源很明确:Cart类的构造函数要求必须传入一个List<Dish>类型的参数,但在NavBar里创建Cart实例时,你直接写了Cart(),没有传入这个必填的参数。

不过这里还有个更深层的问题:原来的代码里,MyHomePage自己维护了_cartList,而NavBar里的Cart是一个全新的实例,两者的购物车数据完全隔离——也就是说,你在首页添加的商品,底部导航栏的购物车页面根本看不到。所以我们需要同时解决两个问题:参数缺失的报错,以及购物车数据在首页和购物车页面之间的共享。

下面是完整的修复方案:

1. 状态提升:将购物车数据移到NavBar中维护

把_cartList从MyHomePage移到NavBar的状态里,这样两个页面都能访问同一个数据源,保证数据同步。

修改NavBar.dart

import 'package:flutter/material.dart';
import 'package:sharewallpaper/cart.dart';
import 'package:sharewallpaper/main.dart';
import 'package:sharewallpaper/dish_object.dart';

class NavBar extends StatefulWidget {
  @override
  _NavBarState createState() => _NavBarState();
}

class _NavBarState extends State<NavBar> {
  int _currentIndex = 0;
  // 把购物车列表移到这里统一维护
  List<Dish> _cartList = [];

  // 提供给子页面的回调,用于更新购物车数据
  void updateCart(Dish item) {
    setState(() {
      if (_cartList.contains(item)) {
        _cartList.remove(item);
      } else {
        _cartList.add(item);
      }
    });
  }

  final List<Widget> _children = [];

  @override
  void initState() {
    super.initState();
    // 初始化页面,传入必要的参数和回调
    _children.addAll([
      MyHomePage(
        title: "Home",
        cartList: _cartList,
        onCartUpdate: updateCart,
      ),
      Cart(cartList: _cartList, onCartUpdate: updateCart),
    ]);
  }

  void onTappedBar(int index) {
    setState(() {
      _currentIndex = index;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: _children[_currentIndex],
      bottomNavigationBar: BottomNavigationBar(
        onTap: onTappedBar,
        currentIndex: _currentIndex,
        items: const [
          BottomNavigationBarItem(icon: Icon(Icons.home), title: Text('Home')),
          BottomNavigationBarItem(icon: Icon(Icons.bookmark), title: Text('BookMark')),
        ],
      ),
    );
  }
}

2. 修改MyHomePage,接收外部的购物车数据和回调

原来的MyHomePage自己维护购物车,现在改成接收从NavBar传入的列表和更新回调,不再单独维护状态:

修改HomePage.dart

// 保留原有导入和Dish类定义

class MyHomePage extends StatefulWidget {
  final String title;
  final List<Dish> cartList;
  final Function(Dish) onCartUpdate;

  const MyHomePage({
    Key? key,
    required this.title,
    required this.cartList,
    required this.onCartUpdate,
  }) : super(key: key);

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  List<Dish> _dishes = [];

  @override
  void initState() {
    super.initState();
    _populateDishes();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
        actions: <Widget>[
          Padding(
            padding: const EdgeInsets.only(right: 16.0, top: 8.0),
            child: GestureDetector(
              child: Stack(
                alignment: Alignment.topCenter,
                children: <Widget>[
                  const Icon(
                    Icons.shopping_cart,
                    size: 36.0,
                  ),
                  if (widget.cartList.isNotEmpty)
                    Padding(
                      padding: const EdgeInsets.only(left: 2.0),
                      child: CircleAvatar(
                        radius: 8.0,
                        backgroundColor: Colors.red,
                        foregroundColor: Colors.white,
                        child: Text(
                          widget.cartList.length.toString(),
                          style: const TextStyle(
                            fontWeight: FontWeight.bold,
                            fontSize: 12.0,
                          ),
                        ),
                      ),
                    ),
                ],
              ),
              // 点击购物车图标时,切换到底部导航栏的购物车页面
              onTap: () {
                if (widget.cartList.isNotEmpty) {
                  final navBarState = context.findAncestorStateOfType<_NavBarState>();
                  navBarState?.onTappedBar(1);
                }
              },
            ),
          )
        ],
      ),
      body: _buildGridView(),
    );
  }

  GridView _buildGridView() {
    return GridView.builder(
      padding: const EdgeInsets.all(4.0),
      gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 2),
      itemCount: _dishes.length,
      itemBuilder: (context, index) {
        var item = _dishes[index];
        return Card(
          elevation: 4.0,
          child: Stack(
            fit: StackFit.loose,
            alignment: Alignment.center,
            children: <Widget>[
              Column(
                mainAxisAlignment: MainAxisAlignment.center,
                children: <Widget>[
                  Icon(
                    item.icon,
                    color: (widget.cartList.contains(item)) ? Colors.grey : item.color,
                    size: 100.0,
                  ),
                  Text(
                    item.name,
                    textAlign: TextAlign.center,
                    style: Theme.of(context).textTheme.subhead,
                  )
                ],
              ),
              Padding(
                padding: const EdgeInsets.only(right: 8.0, bottom: 8.0),
                child: Align(
                  alignment: Alignment.bottomRight,
                  child: GestureDetector(
                    child: (!widget.cartList.contains(item))
                        ? const Icon(Icons.add_circle, color: Colors.green)
                        : const Icon(Icons.remove_circle, color: Colors.red),
                    onTap: () {
                      // 调用回调更新购物车,不再自己维护状态
                      widget.onCartUpdate(item);
                    },
                  ),
                ),
              ),
            ],
          ),
        );
      },
    );
  }

  // 保留原有_populateDishes方法
  void _populateDishes() {
    var list = <Dish>[
      Dish(name: 'Chicken Zinger', icon: Icons.fastfood, color: Colors.amber),
      Dish(name: 'Chicken Zinger without chicken', icon: Icons.print, color: Colors.deepOrange),
      Dish(name: 'Rice', icon: Icons.child_care, color: Colors.brown),
      Dish(name: 'Beef burger without beef', icon: Icons.whatshot, color: Colors.green),
      Dish(name: 'Laptop without OS', icon: Icons.laptop, color: Colors.purple),
      Dish(name: 'Mac wihout macOS', icon: Icons.laptop_mac, color: Colors.blueGrey),
    ];
    setState(() {
      _dishes = list;
    });
  }
}

3. 修改Cart.dart,接收购物车数据和更新回调

让Cart也接收外部的购物车列表和更新回调,确保移除操作能同步到全局数据源:

修改Cart.dart

import 'package:flutter/material.dart';
import 'dish_object.dart';

class Cart extends StatefulWidget {
  final List<Dish> cartList;
  final Function(Dish) onCartUpdate;

  const Cart({
    Key? key,
    required this.cartList,
    required this.onCartUpdate,
  }) : super(key: key);

  @override
  _CartState createState() => _CartState();
}

class _CartState extends State<Cart> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Cart'),
      ),
      body: widget.cartList.isEmpty
          ? const Center(child: Text('Your cart is empty'))
          : ListView.builder(
              itemCount: widget.cartList.length,
              itemBuilder: (context, index) {
                var item = widget.cartList[index];
                return Padding(
                  padding: const EdgeInsets.symmetric(horizontal: 8.0, vertical: 2.0),
                  child: Card(
                    elevation: 4.0,
                    child: ListTile(
                      leading: Icon(item.icon, color: item.color),
                      title: Text(item.name),
                      trailing: GestureDetector(
                        child: const Icon(Icons.remove_circle, color: Colors.red),
                        onTap: () {
                          // 调用回调移除商品
                          widget.onCartUpdate(item);
                        },
                      ),
                    ),
                  ),
                );
              },
            ),
    );
  }
}

方案说明

  • 解决构造函数错误:现在创建Cart实例时,我们传入了必填的cartList和onCartUpdate参数,编译器不会再报错。
  • 数据实时同步:购物车数据由NavBar统一维护,首页和购物车页面共用同一个列表,所有添加/移除操作都会实时同步到两个页面。
  • 优化交互逻辑:点击首页AppBar的购物车图标时,会直接切换到底部导航栏的购物车页面,符合底部导航的交互习惯,避免页面栈混乱。

如果你的项目后续页面增多,也可以考虑使用Provider、Riverpod等状态管理库来管理购物车数据,代码会更简洁易维护。

内容的提问来源于stack exchange,提问作者Jeevan Crasta

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.07 19:52:46