Flutter无FutureBuilder如何实现点击按钮时显示环形进度指示器
实现方案
完全可以不使用FutureBuilder完成这个需求。针对点击按钮触发的异步请求场景,用本地状态变量控制加载状态的实现方式更简单直接,逻辑也更可控。
实现步骤
- 新增
_isLoading布尔状态变量,用来标记当前是否处于请求等待状态 - 点击按钮触发请求前,先将
_isLoading设为true并刷新UI;请求结束(无论成功失败)后,再将_isLoading设为false刷新UI - 在内容展示区域增加加载状态判断:加载中时展示
CircularProgressIndicator,非加载状态走原有业务逻辑展示提示文案或结果卡片 - 可选优化:加载过程中禁用按钮,避免用户重复点击触发多次请求;也可以在按钮内部显示小号加载指示器,交互体验更好
完整修改代码
// 首先在对应的State类中新增加载状态标记 bool _isLoading = false; // 下方为build方法内的组件代码 ElevatedButton( // 加载中时将onPressed置空,按钮自动进入禁用状态,拦截重复点击 onPressed: _isLoading ? null : () async { setState(() { _isLoading = true; }); try { await postML( _mySelectionFeat1, _mySelectionFeat2, _mySelectionFeat3, _mySelectionValue1, _mySelectionValue2, _mySelectionValue3 ); // 此处保留你原有请求完成后更新ShowDogCard、BreedList等业务变量的逻辑即可 } catch (e) { // 按需添加请求失败的提示逻辑,比如SnackBar提示 } finally { // 判断组件是否仍在挂载,避免页面销毁后调用setState触发报错 if (mounted) { setState(() { _isLoading = false; }); } } }, // 按钮内可选择显示小号加载指示器,也可以直接保留原有Text child: _isLoading ? const SizedBox( width: 20, height: 20, child: CircularProgressIndicator( strokeWidth: 2, color: Colors.white, ), ) : const Text('Post'), ), // 内容展示区域 _isLoading ? const Center( child: CircularProgressIndicator(), ) : ShowDogCard == false ? const Center( child: Text('Please select features and values'), ) : Container( child: ListCard( screen: 'ML', doglist: BreedList, index: idxBreedListPredicted, ), ),
补充说明
FutureBuilder更适合与组件生命周期绑定、随组件初始化自动触发的异步请求场景;这种由用户交互触发的短链路异步操作,用本地状态控制加载逻辑的代码可读性更高,也不需要额外处理Future缓存、重复重建等问题,是这类场景的常规实现方案。
内容的提问来源于stack exchange,提问作者Lash
相关产品推荐
相关产品推荐

