如何在flutter_native_splash中使用Provider?Provider失效问题求助
问题分析与修复方案
原代码核心问题
main函数无有效BuildContext:直接调用Provider.of<StockCodeNotifier>(context)会报错,此时Widget树还未初始化,不存在可用上下文。- 未适配异步数据获取:从服务器拉取数据是异步操作,原代码用同步逻辑处理,无法正确等待数据加载完成。
- 启动屏移除时机错误:
main中直接调用FlutterNativeSplash.remove(),会导致数据未加载完成就移除启动屏,状态未正确初始化。
修复步骤
1. 修改StockCodeNotifier,适配异步请求与状态控制
class StockCodeNotifier extends ChangeNotifier { final List<StockModel> _stocks = []; String _stockCode = ''; bool _isLoading = true; // 新增加载状态,用于控制启动屏与UI显示 String get stockCode => _stockCode; bool get isLoading => _isLoading; // 改为异步方法,适配服务器请求场景 Future<void> getStocks() async { try { // 替换为你的实际服务器API调用 await Future.delayed(const Duration(seconds: 2)); List<StockModel> data = allStocks; _stocks.clear(); _stocks.addAll(data); _stockCode = _stocks[0].code; } catch (e) { // 处理请求错误,设置默认值 _stockCode = 'DEFAULT'; } finally { _isLoading = false; notifyListeners(); // 更新状态通知UI } } }
2. 调整main.dart启动流程,正确触发数据加载与启动屏移除
void main() { WidgetsBinding widgetsBinding = WidgetsFlutterBinding.ensureInitialized(); FlutterNativeSplash.preserve(widgetsBinding: widgetsBinding); runApp(const MyApp()); } class MyApp extends StatelessWidget { const MyApp({super.key}); @override Widget build(BuildContext context) { return ChangeNotifierProvider<StockCodeNotifier>( create: (_) => StockCodeNotifier(), child: MaterialApp( title: 'Flutter Demo', theme: ThemeData( primarySwatch: Colors.blue, visualDensity: VisualDensity.adaptivePlatformDensity, ), home: const Home(), ), ); } } class Home extends StatefulWidget { const Home({super.key}); @override State<Home> createState() => _HomeState(); } class _HomeState extends State<Home> { @override void initState() { super.initState(); // 页面初始化时触发数据加载,完成后移除启动屏 _loadDataAndFinishSplash(); } Future<void> _loadDataAndFinishSplash() async { // listen: false 避免不必要的UI重建 final stockNotifier = Provider.of<StockCodeNotifier>(context, listen: false); await stockNotifier.getStocks(); FlutterNativeSplash.remove(); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: const Text('股票页面')), body: Consumer<StockCodeNotifier>( builder: (context, notifier, child) { if (notifier.isLoading) { // 启动屏未移除时,无需显示额外UI return const SizedBox.shrink(); } return Center(child: Text('当前股票代码:${notifier.stockCode}')); }, ), ); } }
内容的提问来源于stack exchange,提问作者broheat
相关产品推荐
相关产品推荐

