Flutter GetX中如何让Text首次加载就显示函数计算的百分比结果
问题根因
首次打开无法显示结果,手动刷新才正常,核心是三个问题:
- 首帧渲染时异步数据还没加载完成,
ps列表为空,此时countP(idC)返回0,直接做除法会触发除以零的运行时错误,导致首帧渲染空白;等手动刷新时异步数据已经就位,运算正常就可以显示结果。 - 你提前把
percentPd定义成普通final变量,脱离了GetX的响应式链路:哪怕ps是响应式列表,提前计算好的普通变量不会跟随数据变化自动更新,就算用Obx包裹组件,也监听不到变化触发重绘。 Text组件要求传入字符串类型参数,直接传int类型本身就会触发类型错误。
修复方案
1. 确认控制器内列表为响应式类型
首先检查控制器里的ps必须是用.obs声明的响应式列表,普通List的变化不会触发UI更新:
class PdController extends GetxController { // 正确写法:响应式列表,数据变更自动通知监听者 final ps = <PdModel>[].obs; // 错误写法:普通列表,变更不触发UI刷新 // List<PdModel> ps = []; // 原有的两个统计方法不需要改动 int countP(String idC) { final _ps = ps.where((element) => element.idC == idC); return _ps.length; } int countPP(String idC) { final _ps = ps.where((element) => element.idC == idC); final _psPd = _ps.where((element) => element.pd != ''); return _psPd.length; } }
2. 把百分比计算放到Obx响应式上下文,处理除零边界
删掉提前计算percentPd的代码,直接在Obx包裹的组件内做计算,同时处理总数为0的情况,避免除零错误:
// 删掉这行:final percentPd =((pCtrl.countPP(idC) * 100) / pCtrl.countP(idC)).round(); Obx(() { final total = pCtrl.countP(idC); // 总数为0时默认显示0,避免除以零异常 final percentPd = total == 0 ? 0 : ((pCtrl.countPP(idC) * 100) / total).round(); // 数值转字符串后传入Text组件 return Text('$percentPd%'); })
3. 确认数据拉取时机正确
如果ps的数据来自接口请求,把拉取逻辑放到控制器的onInit生命周期里,保证页面进入时就开始加载数据,不要等视图渲染完成后再触发请求:
class PdController extends GetxController { final ps = <PdModel>[].obs; @override void onInit() { super.onInit(); // 初始化时就拉取数据 loadPsData(); } Future<void> loadPsData() async { // 替换成你的实际接口请求逻辑 final data = await yourApiRequest(); ps.assignAll(data); } // 省略countP、countPP方法 }
效果说明
修改后首帧加载时如果数据未返回,会先显示0%,不会出现空白;接口数据返回后,Obx会自动监听到ps列表的变化,重新计算百分比并刷新UI,不需要手动触发刷新,也不会再出现除以零的运行时错误。
内容的提问来源于stack exchange,提问作者JoseO
相关产品推荐
相关产品推荐

