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
相关产品推荐
相关产品推荐

