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

Flutter使用sticky_header展示API返回疫苗列表的卡片渲染问题求助

修复方案

核心问题有两个:

  • ListView.builder未指定itemCount为头部数组的长度,列表不知道要渲染多少个分组,无法正常展示内容
  • 子列表渲染逻辑错误,你当前把所有子数据拼接在同一个ListTile里,没有为每个子数据单独生成对应控件

直接替换build方法内的列表相关代码即可,修复后的完整代码如下:

@override
Widget build(BuildContext context) {
  return Scaffold(
    key: scaffoldKey,
    drawerScrimColor: Colors.transparent,
    extendBody: true,
    drawer: ComplexDrawer(),
    appBar: AppBar(
      leading: InkWell(
        child: Icon(
          Icons.menu,
          color: Colors.indigo,
        ),
        onTap: () {
          if (drawerOpen) {
            scaffoldKey.currentState.openDrawer();
          }
        },
      ),
      centerTitle: true,
      title: Text(
        '疫苗接种',
        style: GoogleFonts.ubuntu(
          fontSize: 30,
          color: Colors.indigo,
        ),
      ),
      backgroundColor: Colors.white,
      actions: [
        InkWell(
          child: Padding(
            padding: const EdgeInsets.all(16.0),
            child: Icon(
              Icons.search,
              color: Colors.indigo,
              size: 30,
            ),
          ),
          onTap: () {},
        ),
      ],
      elevation: 1,
    ),
    body: isloading
        ? CustomLoader(size: 50, color: Colors.indigoAccent)
        : Padding(
            padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 16),
            child: ListView.builder(
              // 新增:指定分组总数
              itemCount: header.length,
              itemBuilder: (context, index) {
                // 过滤当前分组对应的子疫苗列表
                final currentSubList = _vaccine.data
                    .where((i) => i.vaccineAgeCriteria == header[index])
                    .toList();
                return StickyHeaderBuilder(
                  builder: (context, stuckAmount) {
                    stuckAmount = stuckAmount.clamp(0.0, 1.0);
                    return Container(
                      height: 100.0 - (50 * (1 - stuckAmount)),
                      color: Color.lerp(Colors.blue, Colors.red, stuckAmount),
                      padding: EdgeInsets.symmetric(horizontal: 16.0),
                      alignment: Alignment.centerLeft,
                      child: Text(
                        header[index],
                        style: const TextStyle(color: Colors.white),
                      ),
                    );
                  },
                  // 修复子列表渲染逻辑:遍历每个子项生成Card+ListTile
                  content: Column(
                    children: currentSubList.map((vaccineItem) {
                      return Card(
                        margin: const EdgeInsets.symmetric(vertical: 4, horizontal: 8),
                        child: ListTile(
                          title: Text(vaccineItem.vaccine),
                          subtitle: Text("剂量:${vaccineItem.dose} | 接种日期:${newFormat.format(DateTime.parse(vaccineItem.vaccineDate))}"),
                        ),
                      );
                    }).toList(),
                  ),
                );
              },
            ),
          ),
  );
}

优化说明

  1. 给ListView.builder补充了itemCount: header.length参数,确保每个分组都能正常渲染
  2. 移除了原来硬编码的子容器高度,改为遍历每个子疫苗数据生成独立的Card和ListTile,布局更灵活
  3. 补充了子项的次要信息展示,包括剂量和格式化后的接种日期,信息展示更完整
  4. 移除了State类里全局的subtitle变量,改为在itemBuilder内生成当前分组的子列表,避免变量污染导致的渲染异常

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 12:06:03