Flutter 2.5迁移至3.0.5后列表赋值失败,求SingleChildScrollView内传值方法
Flutter 2.5→3.0.5迁移后列表数据为空问题修复
问题根源
从报错截图看,核心是类型转换错误:你直接将snapshot.data强转为List<B023_RepVirtual>,但_getMultiplasFuture()的返回值实际是包含多组不同类型数据的集合(比如索引1对应B023_RepVirtual列表、索引2对应B024_RelacionaPessoaRepVirtual列表),强转导致初始化的B023列表直接报错,后续数据传递自然失效。另外Flutter 3.x的空安全校验更严格,原2.5版本的松散空处理在迁移后暴露问题。
修复步骤
1. 修正snapshot.data的类型处理
放弃错误的强转,先将snapshot.data转为List<dynamic>,再分别取出对应索引的列表:
// 替换原来的错误初始化代码 List<B023_RepVirtual> B023 = []; List<B023_RepVirtual> B023_Empresas = []; if (snapshot.hasData) { final dataList = snapshot.data as List<dynamic>; // 先校验数据结构完整性,避免索引越界 if (dataList.length >=3 && dataList[1] != null && dataList[2] != null) { final List<B023_RepVirtual>? temp1 = dataList[1] as List<B023_RepVirtual>?; final List<B024_RelacionaPessoaRepVirtual>? temp2 = dataList[2] as List<B024_RelacionaPessoaRepVirtual>?; // 非空校验后再处理数据 if (temp1 != null && temp2 != null) { temp2.forEach((e1) { final temp3 = temp1.where((e2) => e2.B023_ID == e1.B023_IDRep && e1.B024_DataLiberacao != "0001-01-01T00:00:00"); // 用isNotEmpty替代length判断,符合Dart 3.x写法 if (temp3.isNotEmpty) { final temp4 = temp3.first; B023.add(temp4); B023_Empresas.add(temp4); print("Saindo do mapa: Dados mapa " + '$B023'); } else { final b = B023_RepVirtual(); b.B023_NomeFantasia = "Falha ao buscar empresas!"; B023.add(b); B023_Empresas.add(b); print("Saindo do mapa: Dados mapa " + '$B023'); } }); } } }
2. 空安全细节优化
- 新增
dataList长度校验,避免索引越界异常 - 对
temp1和temp2增加非空判断,防止后续forEach触发空指针 - 用
temp3.isNotEmpty替代temp3?.length !=0,更符合Dart空安全规范
3. 确保SingleChildScrollView内的数据传递正常
修复后的B023列表是正确初始化并填充数据的,后续传递给MinhaContaCardEmpresas(B023)即可正常接收数据。如果MinhaContaCardEmpresas内部是列表渲染组件,确保它接收List<B023_RepVirtual>类型参数并正确遍历渲染。
修改后的完整build方法关键部分
@override Widget build(BuildContext context) { print("Empresas: " + '$B023'); return Scaffold( appBar: AppBar( title: Text("Minha Conta"), ), body: SingleChildScrollView( padding: EdgeInsets.all(16.0), child: FutureBuilder( future: _getMultiplasFuture(), builder: (context, snapshot) { switch (snapshot.connectionState) { case ConnectionState.none: case ConnectionState.waiting: return MinhaContaPlaceholder(); case ConnectionState.active: case ConnectionState.done: // 正确初始化空列表 List<B023_RepVirtual> B023 = []; List<B023_RepVirtual> B023_Empresas = []; if (snapshot.hasData) { final dataList = snapshot.data as List<dynamic>; // 校验数据结构完整性 if (dataList.length >=3 && dataList[1] != null && dataList[2] != null) { final List<B023_RepVirtual>? temp1 = dataList[1] as List<B023_RepVirtual>?; final List<B024_RelacionaPessoaRepVirtual>? temp2 = dataList[2] as List<B024_RelacionaPessoaRepVirtual>?; if (temp1 != null && temp2 != null) { temp2.forEach((e1) { final temp3 = temp1.where((e2) => e2.B023_ID == e1.B023_IDRep && e1.B024_DataLiberacao != "0001-01-01T00:00:00"); if (temp3.isNotEmpty) { final temp4 = temp3.first; B023.add(temp4); B023_Empresas.add(temp4); print("Saindo do mapa: Dados mapa " + '$B023'); } else { final b = B023_RepVirtual(); b.B023_NomeFantasia = "Falha ao buscar empresas!"; B023.add(b); B023_Empresas.add(b); print("Saindo do mapa: Dados mapa " + '$B023'); } }); } } } print("Dentro do Conncetion Statte: " + '$B023'); print("Dentro do Conncetion Statte: " + '$B023_Empresas'); return Column(children: [ Container( child: CircleAvatar( backgroundColor: Colors.grey.shade300, child: Icon( Icons.person, size: 64.0, color: Colors.orange, ), radius: 64.0, ), ), Container( child: MinhaContaCardEmpresas(B023), ), Divider(color: Colors.transparent), Divider(color: Colors.transparent), GestureDetector( child: Text("Termos de política e privacidade"), onTap: () { Navigator.push( context, MaterialPageRoute( builder: (context) => ScreenTermosPoliticaPrivacidade(), ), ); }, ), Divider(color: Colors.transparent), Container( height: 24, width: MediaQuery.of(context).size.width, child: GestureDetector( child: Center(child: Text("Deletar minha conta")), onTap: () { confirmarMarcacoes(context); }, ), ), Container( height: 24, width: MediaQuery.of(context).size.width, child: GestureDetector( child: Center(child: Text("Versão: " + "1.0.1")), ), ), ]); } })), ); }
额外建议
- 给
_getMultiplasFuture()定义明确的返回类型,比如Future<List<dynamic>>,或者自定义数据类封装多组返回数据,避免动态类型的隐患 - 迁移后全面检查空安全相关代码,Flutter 3.x对null的校验更严格,避免类似强制类型转换错误
内容的提问来源于stack exchange,提问作者James Lima
相关产品推荐
相关产品推荐

