Flutter中StreamBuilder重复显示数据库前10条数据问题求助
问题解决:Flutter StreamBuilder重复显示数据库数据
问题原因
你代码里的核心问题有两个:
- 多余的嵌套for循环:在
itemInfo.forEach内部又写了for (int i = 0; i < itemInfo.length; i++),这会让每个数据库条目被重复添加itemInfo.length次(也就是10次),直接导致数据重复显示。 - 全局列表未清空:如果
itemsList是全局变量,每次Stream收到数据时都会往里面追加内容,旧数据不会被清除,也会加重重复问题。
修改后的代码
SingleChildScrollView( child: Center( child: Padding( padding: const EdgeInsets.all(8.0), child: Column( mainAxisSize: MainAxisSize.min, children: <Widget>[ StreamBuilder( stream: myRef.orderByKey().limitToFirst(10).onValue, builder: ((context, snapshot) { // 每次重建时创建新列表,避免全局列表的追加问题 List<List<dynamic>> itemsList = []; if (snapshot.hasData && snapshot.data!.snapshot.value != null) { final itemInfo = Map<String, dynamic>.from( snapshot.data!.snapshot.value as Map ); // 只保留forEach遍历,去掉多余的for循环 itemInfo.forEach((key, value) { final nextItem = Map<String, dynamic>.from(value); List<dynamic> item = List.empty(growable: true); item.add(key.toString()); item.add(nextItem['Descripcion']); item.add(nextItem['Cant']); item.add(nextItem['Ubicacion']); item.add(nextItem['Um']); item.add(nextItem['X']); itemsList.add(item); }); } // 用ListView展示数据,比直接toString更友好 return itemsList.isEmpty ? const Text('暂无数据') : SizedBox( height: 400, child: ListView.builder( itemCount: itemsList.length, itemBuilder: (context, index) { final item = itemsList[index]; return ListTile( title: Text(item[1]), subtitle: Text('数量: ${item[2]} | 位置: ${item[3]}'), leading: Text(item[0]), ); }, ), ); }), ), ], ), ), ), )
关键修改点
- 移除嵌套for循环:只通过
forEach遍历每个数据库条目,每个条目只添加一次到列表中。 - 使用局部列表:在builder内部创建
itemsList,避免全局列表的追加问题,每次Stream更新时都会重新生成干净的列表。 - 替换Text为ListView:直接把列表转为字符串展示可读性差,改用
ListView.builder可以更优雅地展示每条数据,也符合滚动场景的需求。
内容的提问来源于stack exchange,提问作者Juan Peralta Torres
相关产品推荐
相关产品推荐

