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

Flutter ListView item点击如何实现不同分类项输出对应内容

Flutter分类列表点击切换对应内容实现方案

你的代码已经实现了分类选中状态的保存,无法切换内容的核心原因是选中的分类状态没有同步到商品列表,且ItemCard写死了只读取家具类(Product)的属性,可以按照以下步骤修改:

步骤1:为分类组件添加状态回调

首先需要把分类组件内部选中的下标同步到父组件,修改Cat类的定义,增加分类切换的回调参数:

class Cat extends StatefulWidget {
  // 新增回调:将选中的分类下标传给父组件
  final ValueChanged<int> onCategorySelected;
  const Cat({super.key, required this.onCategorySelected});

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

然后在_CatState的点击事件中触发回调:

Widget buildCategory(int index) {
  return GestureDetector(
    onTap: () {
      setState(() {
        selectedIndex = index;
      });
      // 新增:触发回调通知父组件选中的分类
      widget.onCategorySelected(index);
    },
    // 原有代码不变
  );
}

步骤2:统一商品数据结构

你目前有Product/Light/Decor三个商品类,建议抽取公共属性作为基类,避免后续重复判断类型:

// 商品公共基类
abstract class Goods {
  String get img;
  String get name;
  String get price;
}

// 让三个商品类都实现基类,原有属性不需要修改
class Product implements Goods {
  @override
  final String img;
  @override
  final String name;
  @override
  final String price;
  // 其他原有属性
  Product({required this.img, required this.name, required this.price});
}

class Light implements Goods {
  // 同Product的实现逻辑
}

class Decor implements Goods {
  // 同Product的实现逻辑
}

步骤3:改造ItemCard兼容多类商品

修改ItemCard只接收公共基类参数,不用分别传三类商品对象:

class ItemCard extends StatelessWidget {
  final Goods goods;
  final Function press;

  const ItemCard({
    super.key,
    required this.press,
    required this.goods,
  }) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return GestureDetector(
      onTap: () => press(),
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: <Widget>[
          Container(
            padding: EdgeInsets.all(2.0),
            child: ClipRRect(
              borderRadius: BorderRadius.circular(25.0),
              child: Image.asset(goods.img),
            ),
          ),
          Padding(
            padding: const EdgeInsets.symmetric(vertical: DefaultPadding / 4),
            child: Text(
              goods.name,
              textAlign: TextAlign.center,
              style: const TextStyle(
                fontWeight: FontWeight.bold,
                fontSize: 18,
              ),
            ),
          ),
          Text(
            goods.price,
            textAlign: TextAlign.center,
            style: const TextStyle(fontStyle: FontStyle.italic),
          )
        ],
      ),
    );
  }
}

步骤4:父组件根据选中分类切换商品列表

父组件中先定义三类商品的数据源、当前选中的分类下标,接收分类组件的回调后刷新列表:

class ParentPageState extends State<ParentPage> {
  // 三类商品的数据源,替换为你自己的实际数据
  List<Product> furnitureList = [];
  List<Light> lightingList = [];
  List<Decor> decorationList = [];
  // 当前选中的分类下标,默认选中第一个
  int currentCatIndex = 0;

  // 根据当前选中的分类返回对应商品列表
  List<Goods> get currentGoodsList {
    switch(currentCatIndex) {
      case 1: return lightingList;
      case 2: return decorationList;
      default: return furnitureList;
    }
  }

  @override
  Widget build(BuildContext context) {
    return Column(
      children: [
        // 分类组件
        Cat(
          onCategorySelected: (index) {
            setState(() {
              currentCatIndex = index;
            });
          },
        ),
        // 商品列表,示例为GridView,你可以替换为自己的列表控件
        Expanded(
          child: GridView.builder(
            itemCount: currentGoodsList.length,
            itemBuilder: (context, index) => ItemCard(
              goods: currentGoodsList[index],
              press: () {
                // 这里就能拿到对应分类的商品数据,处理你的点击逻辑即可
              },
            ),
          ),
        )
      ],
    );
  }
}

你提到的界面截图参考:
界面展示
调用函数展示

内容的提问来源于stack exchange,提问作者Sin Wai Chow

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.11 21:51:02