Flutter的StreamBuilder对接Cloud Firestore报isNotEmpty空指针异常如何解决
问题原因分析
- 首次报错原因:StreamBuilder 首次渲染时,Stream 尚未返回数据,
snapshot.data为 null,直接调用isNotEmpty触发空指针异常 - 修改为
snaphot.hasData后空白原因:当 Firestore 没有匹配查询条件的文档时,你的映射逻辑会返回空的List<Evento>,此时snapshot.hasData为 true,但列表长度为0,进入if分支后ListView没有可渲染的内容,自然显示空白,不会走到else分支。
正确判断逻辑
需要按优先级依次处理四种状态,覆盖所有场景:
- 先判断请求是否出错:
snapshot.hasError,对应显示错误提示 - 再判断是否处于加载中:
snapshot.connectionState == ConnectionState.waiting,对应显示加载占位动画 - 最后判断是否有有效数据:同时满足有数据、且数据非空两个条件,即
snapshot.hasData && snapshot.data!.isNotEmpty - 剩余场景统一走无数据提示分支
修正后的完整代码示例
StreamBuilder<List<Evento>>( stream: eventosProvider.eventosbares, builder: (context, snapshot) { // 处理错误状态 if (snapshot.hasError) { return const Text( "加载活动失败", style: TextStyle(color: Colors.white), ); } // 处理加载中状态,可替换为你自定义的占位组件 if (snapshot.connectionState == ConnectionState.waiting) { return const SizedBox( height: 155, child: Center(child: CircularProgressIndicator(color: Colors.white)), ); } // 判断存在有效数据才渲染列表 if (snapshot.hasData && snapshot.data!.isNotEmpty) { return SizedBox( height: 155, child: ListView.builder( scrollDirection: Axis.horizontal, itemCount: snapshot.data!.length, itemBuilder: (context, index) { var dateString = snapshot.data![index].fechaEvento; var date = DateFormat('d-M-yyyy HH:mm', 'de_DE').parse(dateString); return Card( shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(10), ), child: Container( height: 178, width: 280, child: Column( children: [ Padding( padding: const EdgeInsets.only( left: 8.0, right: 8.0, top: 8.0), child: ClipRRect( borderRadius: BorderRadius.circular(8), child: Image.network( snapshot.data![index].imagenEvento, width: 278.0, height: 80.0, fit: BoxFit.fill, ), ), ), Padding( padding: const EdgeInsets.all(8.0), child: Row( mainAxisAlignment: MainAxisAlignment.start, children: [ CircleAvatar( radius: 20.0, backgroundImage: NetworkImage(snapshot.data![index].fotoPerfilAutor), backgroundColor: Colors.transparent, ), Padding( padding: const EdgeInsets.all(2.0), child: Container( width: 150, child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( snapshot.data![index].tituloEvento, overflow: TextOverflow.ellipsis, style: TextStyle( fontWeight: FontWeight.bold, fontSize: 13, ), ), Text( DateFormat('EEEEE dd MMM yyyy HH:mm', 'es_ES').format(date), style: TextStyle(fontSize: 10), ), ], ), ), ), SizedBox( width: 10, ), Text( snapshot.data![index].num_invitados, style: TextStyle(color: ColoresApp.naranjaTop, fontWeight: FontWeight.bold, fontSize: 14), ), SizedBox( width: 5, ), CircleAvatar( radius: 10.0, backgroundImage: AssetImage("assets/friends.png"), backgroundColor: Colors.transparent, ) ], ), ), ]), ), ); }), ); } // 无数据场景 return const Text( "No hay eventos en bares", style: TextStyle(color: Colors.white), ); } ),
内容的提问来源于stack exchange,提问作者mvasco
相关产品推荐
相关产品推荐

