Flutter中使用Stream Provider时如何展示加载页避免报错
问题原因
你当前的报错核心是两个问题:
StreamProvider初始数据设为null,流还没返回数据时,Home页面直接读取null的用户属性触发空安全报错Provider.of加了listen: false不会监听流的更新,就算后续流返回数据页面也不会刷新
修正方案
不需要用FutureBuilder,直接在读取流数据的页面加加载状态判断即可,调整后的代码如下:
// UserData类原有逻辑无需修改 class UserData { String uid; UserData(this.uid); Stream<UserModel> get getUserData{ return FirebaseDatabase.instance.reference().child('users').child(uid).onValue.map((e) { return UserModel(e.snapshot.key, e.snapshot.value['name'],e.snapshot.value['Email']); }); } } // MainPage类仅需要补全空安全适配即可,原有逻辑无需修改,注意确保传入的user.uid为有效非空值 class MainPage extends StatefulWidget { const MainPage({Key? key}) : super(key: key); @override _MainPageState createState() => _MainPageState(); } class _MainPageState extends State<MainPage> { @override Widget build(BuildContext context) { return StreamProvider<UserModel?>.value( value: UserData(user.uid).getUserData, initialData: null, child: const Home(), ); } } // Home类为核心调整部分 class Home extends StatefulWidget { const Home({Key? key}) : super(key: key); @override _HomeState createState() => _HomeState(); } class _HomeState extends State<Home> { @override Widget build(BuildContext context) { // 去掉listen: false,开启监听流的更新 final UserModel? userData = Provider.of<UserModel?>(context); // 数据为null时展示加载页面 if (userData == null) { return const Scaffold( body: Center( child: CircularProgressIndicator(), ), ); } // 数据加载完成后走原有业务逻辑 else { // 此处修正你原代码中user变量的笔误,替换为userData,可根据实际业务调整判断条件 return userData.role == 'offer' ? const Offer() : const Customer(); } } }
额外优化建议
如果需要处理流加载出错的场景,可以将StreamProvider替换为StreamBuilder,额外增加错误状态处理:
class _MainPageState extends State<MainPage> { @override Widget build(BuildContext context) { return StreamBuilder<UserModel>( stream: UserData(user.uid).getUserData, builder: (context, snapshot) { // 加载出错时展示错误页 if (snapshot.hasError) { return Scaffold(body: Center(child: Text('加载失败:${snapshot.error}'))); } // 加载中展示加载页 if (!snapshot.hasData) { return const Scaffold(body: Center(child: CircularProgressIndicator())); } // 加载成功后传递数据 return Provider.value( value: snapshot.data!, child: const Home(), ); }, ); } }
内容的提问来源于stack exchange,提问作者Asha
相关产品推荐
相关产品推荐

