Flutter页面间传递List触发RangeError,求排查解决方法
解决Flutter传递List时的RangeError问题
核心错误点分析
你遇到的RangeError (index): Invalid value: Valid value range is empty: 0,根源是传递的List为空,同时接收页面直接访问了空列表的索引0,具体问题分两处:
1. 发送页面(ListaDeProdutos)的错误修正
在ListTile的onTap回调里,你传递的是空列表listaproduto: [],而且database参数用了未定义的变量,应该改为当前页面的widget.database和已加载的listaproduto:
错误代码:
Navigator.push( context, MaterialPageRoute(builder: (context) => LeitorCodigoBarras(database: database, listaproduto: [],)), );
修正后:
Navigator.push( context, MaterialPageRoute(builder: (context) => LeitorCodigoBarras(database: widget.database, listaproduto: listaproduto,)), );
2. 接收页面(LeitorCodigoBarras)的错误修正
问题1:State类的listaproduto未关联传入的列表
你在State里定义了独立的listaproduto,但没有用widget传进来的列表初始化,导致扫描时遍历的是空列表。可以直接使用widget.listaproduto,或者在initState里赋值:
@override void initState() { super.initState(); listaproduto = widget.listaproduto; // 关联传入的列表 }
问题2:直接访问空列表的索引0
页面初始化时index=0,但如果传入的列表为空,widget.listaproduto[index]就会触发RangeError。需要添加空列表判断,比如显示占位提示:
错误代码:
title: Text( 'Produto ${widget.listaproduto[index].codigo}', textAlign: TextAlign.center, style: TextStyle(color: Colors.black, fontSize: 40), ),
修正后:
title: widget.listaproduto.isEmpty ? const Text('Nenhum produto encontrado', textAlign: TextAlign.center, style: TextStyle(color: Colors.black, fontSize: 40)) : Text( 'Produto ${widget.listaproduto[index].codigo}', textAlign: TextAlign.center, style: const TextStyle(color: Colors.black, fontSize: 40), ),
问题3:扫描逻辑的错误提示逻辑
当前代码每次循环不匹配都会弹SnackBar,会重复弹出多次。应该遍历完所有元素后,确认没有匹配项再提示:
错误代码:
for (var i = 0; i < listaproduto.length; i++) { if (listaproduto[i].codigoEAN == scanResult) { index = i; }else{ ScaffoldMessenger.of(context) ..removeCurrentSnackBar() ..showSnackBar(const SnackBar(content: Text("Código EAN não encontrado."))); } }
修正后:
bool found = false; for (var i = 0; i < listaproduto.length; i++) { if (listaproduto[i].codigoEAN == scanResult) { index = i; found = true; break; // 找到后直接退出循环 } } if (!found) { ScaffoldMessenger.of(context) ..removeCurrentSnackBar() ..showSnackBar(const SnackBar(content: Text("Código EAN não encontrado."))); }
额外建议
- 在发送页面跳转前,可以先判断
listaproduto是否为空,避免传递空列表到新页面:onTap: () { if (listaproduto.isNotEmpty) { Navigator.push( context, MaterialPageRoute(builder: (context) => LeitorCodigoBarras(database: widget.database, listaproduto: listaproduto,)), ); } else { ScaffoldMessenger.of(context).showSnackBar(const SnackBar(content: Text("Nenhum produto para enviar"))); } },
内容的提问来源于stack exchange,提问作者Bill
相关产品推荐
相关产品推荐

