Flutter使用Wrap+ListView布局报Unsupported operation: add错误如何解决
报错根因
你遇到的Unsupported operation: add报错和外层ListView无关,根本原因是Flutter中Widget的children属性默认是不可修改的固定长度列表,你直接对filters.children调用add方法自然会报错。
另外你当前的写法还有两个明显问题:
- 在
ListView.builder的itemBuilder中调用setState会反复触发页面重绘,轻则出现芯片重复添加,重则导致页面循环刷新卡死 - 没有对分类去重,多个影片包含相同分类时会生成重复的FilterChip
正确实现方案
Flutter的UI更新逻辑是靠状态变化触发重绘实现的,不要提前存储Widget实例再修改,应该改为存储分类数据,在build方法中动态生成Wrap和芯片:
class _ListFilmResultsWidgetState extends State<ListFilmResultsWidget> { // 存储所有去重后的分类 Set<Genre> allGenres = {}; // 存储当前选中的分类 Set<Genre> selectedGenres = {}; @override Widget build(BuildContext context) { return FutureBuilder( builder: (context, projectSnap) { switch(projectSnap.connectionState) { case ConnectionState.waiting: return const Center(child: CircularProgressIndicator()); case ConnectionState.done: if(projectSnap.hasData){ List<Film>? listFilms = projectSnap.data as List<Film>?; // 拿到影片列表后先收集所有去重的分类,仅执行一次 if (allGenres.isEmpty) { for (var film in listFilms!) { allGenres.addAll(film.genres); } // 需要默认全选的话打开下面这行 // selectedGenres.addAll(allGenres); } return ListView( children: [ // 动态构建Wrap组件 Wrap( direction: Axis.horizontal, spacing: 8, // 芯片水平间距 runSpacing: 4, // 换行后垂直间距 children: allGenres.map((genre) { return FilterChip( label: Text(genre.name), key: Key("${genre.id}"), selected: selectedGenres.contains(genre), onSelected: (isSelected) { setState(() { if (isSelected) { selectedGenres.add(genre); } else { selectedGenres.remove(genre); } // 此处可补充筛选影片列表的逻辑 }); }, ); }).toList(), ), ListView.builder( itemCount: listFilms!.length, scrollDirection: Axis.vertical, shrinkWrap: true, // 禁止内嵌ListView滚动,避免和父容器滚动冲突 physics: const NeverScrollableScrollPhysics(), itemBuilder: (context, index) { Film item = listFilms[index]; // 需要筛选的话可以在此判断影片分类是否在selectedGenres中,不符合返回SizedBox.shrink()即可 return Card( child: Center( child: ListTile( title: Text('${item.title} (${item.releaseYear})'), subtitle: Text(item.plot!), ), ) ); }, ) ] ); } default: return Container(); } }, future: _getFilmsDetails(context) ); } }
内容的提问来源于stack exchange,提问作者user1012480
相关产品推荐
相关产品推荐

