Flutter StreamBuilder报错:非空Widget返回类型可能返回null
Flutter StreamBuilder编译报错:builder回调可能返回null
报错信息
- 报错定位代码行:
builder: (BuildContext context, AsyncSnapshot<QuerySnapshot> snapshot) { - 核心错误提示:
The body might complete normally, causing 'null' to be returned, but the return type, 'Widget', is a potentially non-nullable type
翻译:函数体可能在正常执行流程结束后返回null,但指定的返回类型Widget是非可空类型,不允许返回null。 - 控制台完整日志:
- 正在SM G780G设备上以debug模式启动
lib\main.dart,执行Gradle任务assembleDebug... - 编译错误:
lib/screens/conversas.dart:13:18: Error: A non-null value must be returned since the return type 'Widget' doesn't allow null。其中Widget类型定义来自package:flutter/src/widgets/framework.dart,错误锚点在StreamBuilder的builder回调定义位置。 - 构建失败:任务
:app:compileFlutterBuildDebug执行失败,进程command 'C:\src\flutter\bin\flutter.bat'退出码为1,最终提示BUILD FAILED in 17s,Gradle任务assembleDebug执行失败。
- 正在SM G780G设备上以debug模式启动
故障原代码
Widget build(BuildContext context) { return StreamBuilder<QuerySnapshot>( stream: FirebaseFirestore.instance.collection("Conversas").snapshots(), builder: (BuildContext context, AsyncSnapshot<QuerySnapshot> snapshot) { if (snapshot.hasError) { return Center( child: Text("Desculpe. Aconteceu algum erro de nossa parte. =(") ); //Center } if(snapshot.connectionState == ConnectionState.waiting){ return Center( child: Text("Carregando") ); //Center } if(snapshot.hasData) { return CustomScrollView( slivers: [ CupertinoSliverNavigationBar( largeTitle: Text('Conversas'), ), //CupertinoSliverNavigationBar SliverList( delegate: SliverChildListDelegate( snapshot.data!.docs.map((DocumentSnapshot document){ return Container(); }).toList())) //SliverChildListDelegate, SliverList ], ); //CustomScrollView } }); //StreamBuilder }
错误原因
Dart空安全校验规则要求:返回值标注为非可空类型的函数,必须保证所有执行分支都有明确的非空返回值。
当前代码的builder函数只覆盖了3种分支逻辑:
- snapshot存在错误时返回错误提示组件
- 连接状态为等待中时返回加载提示组件
- snapshot持有有效数据时返回滚动列表组件
但没有覆盖剩余的边界场景(比如无错误、非等待状态、同时也无有效数据的情况),这类分支下函数没有任何返回值,会被判定为可能返回null,直接触发编译阻断。
修复方法
在builder函数的所有分支判断末尾,增加兜底的返回组件,覆盖所有未被前面逻辑处理的场景即可。兜底组件可以根据业务需求选择空状态提示、加载组件等。
修复后完整代码
Widget build(BuildContext context) { return StreamBuilder<QuerySnapshot>( stream: FirebaseFirestore.instance.collection("Conversas").snapshots(), builder: (BuildContext context, AsyncSnapshot<QuerySnapshot> snapshot) { if (snapshot.hasError) { return const Center( child: Text("Desculpe. Aconteceu algum erro de nossa parte. =(") ); } if(snapshot.connectionState == ConnectionState.waiting){ return const Center( child: Text("Carregando") ); } if(snapshot.hasData) { return CustomScrollView( slivers: [ const CupertinoSliverNavigationBar( largeTitle: Text('Conversas'), ), SliverList( delegate: SliverChildListDelegate( snapshot.data!.docs.map((DocumentSnapshot document){ return Container(); }).toList() ) ) ], ); } // 兜底返回,覆盖所有剩余分支 return const Center( child: Text("Nenhum dado disponível"), ); } ); }
内容的提问来源于stack exchange,提问作者Mateus Vitor
相关产品推荐
相关产品推荐

