Flutter Stateful类列表初始加载触发Infinity异常如何解决
问题根因
页面初始加载时,Firestore 数据拉取是异步逻辑,在 _loadAllMemoCardsInDeck() 执行完成、触发 notifyListeners() 推送更新前,动画组件的百分比计算逻辑拿到的列表值不满足计算要求——常见场景是计算进度时做了「当前值/列表总长度」的除法,初始阶段列表长度取值异常触发除零运算,最终算出 Infinity 传给了仅接受 0.0~1.0 区间双精度浮点数的百分比参数,因此抛出异常。等数据加载完成后列表长度为合法有效值,计算和渲染自然恢复正常。
修复方案
以下方案可单独使用,组合使用鲁棒性更强:
- 增加加载态兜底,数据未就绪时不渲染依赖列表长度的动画组件
先在状态类中新增加载状态标记,改造原有加载逻辑:
在bool isLoading = false; List<MemoCard?>? allCardsInDeck = []; Future<void> _loadAllMemoCardsInDeck() async { isLoading = true; notifyListeners(); try { final QuerySnapshot snapDecks = await firestore.collection('users/$clientID/decks/${deck?.idDeck}/cards').get(); allCardsInDeck = snapDecks.docs.map((e) => MemoCard.fromDocument(e)).toList(); } catch (e) { allCardsInDeck = []; } finally { isLoading = false; notifyListeners(); } }Consumer构建逻辑中根据加载状态分流渲染:Consumer<你的Provider状态类>( builder: (context, provider, child) { if (provider.isLoading) { // 加载阶段渲染占位组件,如骨架屏、加载指示器 return const Center(child: CircularProgressIndicator()); } // 数据就绪后再渲染带动画的业务组件 return 你的业务动画组件( // 此时传入的计算参数均为合法值 ); } ) - 给百分比计算加合法值兜底,全阶段保证传入参数在合法区间
就算不做加载态分流,在计算动画组件的percent参数时强制做边界校验,从根源避免非法值传入:
把经过校验的// 示例为进度百分比计算逻辑,可根据你的实际计算规则调整 final int totalCount = provider.allCardsInDeck?.length ?? 0; double percent = 0.0; // 仅当列表长度大于0时才做除法运算,避免除零 if (totalCount > 0) { percent = 你的计算值 / totalCount; } // 最后做强制区间钳制,确保值永远落在0.0~1.0范围内 percent = percent.clamp(0.0, 1.0);percent传给动画组件,即使处于初始加载阶段,传入的也是合法默认值,不会触发异常。
核心原则:所有依赖异步数据的渲染逻辑,必须覆盖数据未就绪的中间态,要么暂不渲染对应组件,要么传入合法默认参数,不能让未加载完成的异常值直接流入组件参数计算环节。
内容的提问来源于stack exchange,提问作者Waldson Fagundes
相关产品推荐
相关产品推荐

