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

ListView.builder嵌套Wrap组件出现数据重复问题的解决方法

解决ListView.builder嵌套Wrap导致日期列表重复的问题

问题原因

你的代码核心问题是重复渲染了整个日期列表:ListView.builder的itemCount设为了days.length,意味着会生成和日期数量一样多的列表项;但每个列表项内部又通过days.map遍历了所有日期,等于每一个ListView项都渲染了全部日期卡片,最终出现重复。

解决方案

根据你的实际需求,选下面两种方案之一:

方案1:直接用Wrap展示(推荐,无多余嵌套)

如果只是需要日期卡片自动换行排列,完全不需要外层的ListView.builder,直接用Wrap包裹遍历后的日期卡片即可:

Wrap(
  children: <Widget>[
    ...days.asMap().entries.map((entry) {
      final index = entry.key;
      final date = entry.value;
      return Container(
        width: MediaQuery.of(context).size.width / 2.4,
        decoration: const BoxDecoration(
          borderRadius: BorderRadius.all(Radius.circular(20.0)),
          color: Colors.white,
        ),
        child: ListTile(
          onTap: () {
            Navigator.pushNamed(context, '/logEntry');
          },
          title: DefaultText(
            size: 18,
            text: "Day ${index + 1}", // 动态生成Day编号
            color: Colors.green,
            weight: FontWeight.w500,
          ),
          subtitle: DefaultText(
            size: 15,
            text: "${date.day}/${date.month}/${date.year}",
            color: Colors.green,
            weight: FontWeight.w500,
          ),
          trailing: const Icon(Icons.arrow_forward_ios),
        ),
      );
    }).toList(),
  ],
)

方案2:保留外层ListView(仅当有其他滚动内容时使用)

如果必须保留外层的ListView(比如Wrap是滚动页面的一部分),只需把ListView的itemCount改为1,让它只渲染一次包含所有日期的Wrap:

ListView.builder(
  physics: const NeverScrollableScrollPhysics(),
  scrollDirection: Axis.vertical,
  shrinkWrap: true,
  // 改为1,只生成一个列表项
  itemCount: days == null ? 0 : 1,
  itemBuilder: (BuildContext context, int index) {
    return Wrap(
      children: <Widget>[
        ...days.asMap().entries.map((entry) {
          final idx = entry.key;
          final date = entry.value;
          return Container(
            width: MediaQuery.of(context).size.width / 2.4,
            decoration: const BoxDecoration(
              borderRadius: BorderRadius.all(Radius.circular(20.0)),
              color: Colors.white,
            ),
            child: ListTile(
              onTap: () {
                Navigator.pushNamed(context, '/logEntry');
              },
              title: DefaultText(
                size: 18,
                text: "Day ${idx + 1}", // 动态生成Day编号
                color: Colors.green,
                weight: FontWeight.w500,
              ),
              subtitle: DefaultText(
                size: 15,
                text: "${date.day}/${date.month}/${date.year}",
                color: Colors.green,
                weight: FontWeight.w500,
              ),
              trailing: const Icon(Icons.arrow_forward_ios),
            ),
          );
        }).toList(),
      ],
    );
  },
)

额外优化

原来代码中title的"Day 1"是固定值,上面的方案用asMap().entries获取索引,动态生成Day编号,让每个卡片的标题更合理。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.31 05:27:24