Dart/Flutter对比两个模型列表实现ExpansionListTile子项过滤
Flutter ExpansionList 店铺对应专属菜单实现方案
1. 核心逻辑修正
你当前的代码存在两个核心逻辑问题:
- 原有列表的
where过滤条件element.shopTitle == element.shopTitle是恒成立的判断,没有任何过滤效果 - 两个模型没有关联规则,无法直接匹配对应菜单,有两种可行的关联方案:
- 方案1:为
CoffeeShopMenu新增relatedShopTitle字段,存储对应店铺的名称,匹配时用where过滤出relatedShopTitle等于当前店铺名称的菜单即可 - 方案2:如果确定店铺和菜单的顺序是一一对应的(列表顺序完全对齐),可以直接通过索引对应,无需修改模型
- 方案1:为
- 你在
itemBuilder中写的双层forEach逻辑没有任何实际作用,返回值不会被使用,可以直接删除
2. 布局报错解决
你遇到的hasSize报错是因为ExpansionTile的children中嵌套的ListView.builder默认会占用无限高度,父组件没有提供明确的布局约束,只需要给内部ListView添加两个属性即可解决:
shrinkWrap: true, physics: const NeverScrollableScrollPhysics(),
shrinkWrap让ListView根据子组件高度自适应,NeverScrollableScrollPhysics禁用内部ListView的滚动,避免和外部ListView滚动冲突。
3. 完整可运行修正代码
这里采用方案2(索引对应)实现,和你现有列表顺序匹配:
class ExpList extends StatelessWidget { // 去掉无用的where过滤 List<CoffeeShop> coffeeShop = <CoffeeShop>[ CoffeeShop(shopTitle: 'Starbucks'), CoffeeShop(shopTitle: 'Dunkin doghnuts'), CoffeeShop(shopTitle: 'Subway'), CoffeeShop(shopTitle: 'MCCafe'), CoffeeShop(shopTitle: 'Coffee Shop'), ]; List<CoffeeShopMenu> coffeeMenu = <CoffeeShopMenu>[ CoffeeShopMenu(shopMenuTitle: 'Latte and americano'), CoffeeShopMenu(shopMenuTitle: 'Matcha'), CoffeeShopMenu(shopMenuTitle: 'pie'), CoffeeShopMenu(shopMenuTitle: 'sandwich'), CoffeeShopMenu(shopMenuTitle: 'croissant'), ]; // 预先把对应关系存在Map里,匹配逻辑更灵活 late Map<String, CoffeeShopMenu> shopMenuMap = Map.fromIterables( coffeeShop.map((e) => e.shopTitle), coffeeMenu, ); @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(), body: ListView.builder( itemCount: coffeeShop.length, itemBuilder: (context, index) { // 获取当前店铺对应的菜单 final currentShop = coffeeShop[index]; final currentMenu = shopMenuMap[currentShop.shopTitle]; return ExpansionTile( title: Text(currentShop.shopTitle), subtitle: Text(currentShop.shopTitle), children: [ ListView.builder( shrinkWrap: true, physics: const NeverScrollableScrollPhysics(), // 单个店铺对应多个菜单时,改为对应菜单列表的长度即可 itemCount: 1, itemBuilder: (context, menuIndex) { return ListTile( title: Text(currentMenu?.shopMenuTitle ?? '暂无菜单'), ); }, ) ], ); }, ), ); } }
如果需要单个店铺对应多个菜单,只需要把shopMenuMap的value类型改成List<CoffeeShopMenu>,存储每个店铺对应的菜单列表即可。
内容的提问来源于stack exchange,提问作者user15037387
相关产品推荐
相关产品推荐

