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

Flutter如何从Store类的嵌套列表中获取Product商品数据

修复方案与优化建议

一、先修正现有代码的语法错误

你的Store类存在三处明显语法问题,会直接影响数据读取:

  1. 构造函数参数错误:定义了products属性,但构造函数中写了不存在的features、price参数,需替换为products
  2. 门店列表未声明为静态:你直接用Store.store调用该列表,需加static关键字才能通过类名直接访问
  3. 字符串拼写错误:name: "Ikea:多了一个冒号在引号内,需修正

修正后的完整代码如下:

// 你需要先保证Product类已正确定义
class Product {
  final String name;
  final String description;
  final double price;
  Product({required this.name, required this.description, required this.price});
}

class Store{
  final String name;
  final String image;
  final List<Product> products; 

  Store({
    required this.name, 
    required this.image, 
    required this.products
  });

  // 静态全局门店列表
  static const List<Store> storeList = [
    Store(
      name: "Ikea", 
      image: "ikealogo.png",
      products :[
        Product(name: "wood table", description: "a very nice wood table", price: 12.50),
        Product(name: "comfy chair", description: "a very nice leather chair", price: 10.50),
        Product(name: "awesome lamp", description: "an ultra bright lamp", price: 5.50),
      ]
    ),
    Store(
      name: "Bestbuy", 
      image: "bestbuylogo.png",
      products :[
        Product(name: "television", description: "a very nice television", price: 350.00),
        Product(name: "radio", description: "a very loud radio", price: 15.50),
        Product(name: "cellphone", description: "a very small phone", price: 78.50),
      ]
    ),
    // 剩余20+门店继续按此格式添加
  ];
}

二、选中门店后提取商品列表的正确逻辑

你原有代码的问题在于:map方法本身会返回Iterable类型,且你不需要遍历所有门店提取商品,只要获取用户选中的那一个门店的products属性即可,它本身就是List<Product>类型,不需要额外转换。

实现示例代码如下:

class StorePage extends StatefulWidget {
  const StorePage({super.key});

  @override
  State<StorePage> createState() => _StorePageState();
}

class _StorePageState extends State<StorePage> {
  // 存储当前选中的门店
  Store? selectedStore;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Column(
        children: [
          // 顶部横向门店选择列表
          SizedBox(
            height: 100,
            child: ListView.builder(
              scrollDirection: Axis.horizontal,
              padding: const EdgeInsets.symmetric(horizontal: 12),
              itemCount: Store.storeList.length,
              itemBuilder: (context, index) {
                final store = Store.storeList[index];
                final isSelected = selectedStore == store;
                return GestureDetector(
                  onTap: () {
                    // 点击门店时更新选中状态
                    setState(() {
                      selectedStore = store;
                    });
                  },
                  child: Container(
                    margin: const EdgeInsets.only(right: 12),
                    padding: const EdgeInsets.all(8),
                    decoration: BoxDecoration(
                      border: isSelected ? Border.all(color: Colors.blue, width: 2) : null,
                      borderRadius: BorderRadius.circular(8),
                    ),
                    child: Column(
                      children: [
                        Image.asset(store.image, width: 50, height: 50),
                        const SizedBox(height: 4),
                        Text(store.name),
                      ],
                    ),
                  ),
                );
              },
            ),
          ),
          const Divider(height: 1),
          // 下方商品列表展示区域
          if (selectedStore != null)
            Expanded(
              child: ListView.builder(
                padding: const EdgeInsets.all(12),
                // 直接取选中门店的products列表作为数据源
                itemCount: selectedStore!.products.length,
                itemBuilder: (context, index) {
                  final product = selectedStore!.products[index];
                  return ListTile(
                    title: Text(product.name),
                    subtitle: Text(product.description),
                    trailing: Text("¥${product.price.toStringAsFixed(2)}"),
                  );
                },
              )
            )
          else
            const Expanded(child: Center(child: Text("请选择门店查看商品")))
        ],
      ),
    );
  }
}

三、可选数据结构优化建议

  • 给Store、Product类增加唯一id字段(int或String类型),后续查找、过滤数据时不依赖列表索引,避免列表顺序变更导致的逻辑错误
  • 可将静态门店列表抽离到独立的常量文件,不要耦合在Store类内部,方便后续维护扩展
  • 可根据业务需求给Store类扩展商品筛选方法,比如按价格区间过滤商品,减少业务层重复代码

内容的提问来源于stack exchange,提问作者Mark Panaguiton

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 20:42:02