Flutter点击按钮调用API时显示进度条的问题及代码修正
问题分析与修正代码
原代码的核心问题:
- 点击按钮无反应:调用
getFokatKiAdvice()后未触发UI刷新,且FutureBuilder的future参数每次build都会重新执行请求,无法与按钮点击操作关联 - 加载状态不符合预期:
FutureBuilder的加载状态仅在初始渲染时生效,点击按钮后无法重新显示加载指示器
下面是修正后的代码:
class _MyHomePageState extends State<MyHomePage> { String? _advice; bool _isLoading = false; String? _errorMessage; // 重构API调用方法,更新状态变量触发UI刷新 Future<void> _fetchAdvice() async { setState(() { _isLoading = true; _errorMessage = null; }); try { final response = await http.get(Uri.parse("https://api.adviceslip.com/advice")); if (response.statusCode == 200) { var resp = json.decode(response.body); setState(() { _advice = resp['slip']['advice']; }); } else { setState(() { _errorMessage = "请求失败,请重试"; }); } } catch (e) { setState(() { _errorMessage = "Oye !! Thare pass Internet naahi hn !!"; }); } finally { setState(() { _isLoading = false; }); } } @override void initState() { super.initState(); // 页面初始化时加载第一条建议 _fetchAdvice(); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text(widget.title), ), body: Center( child: Padding( padding: const EdgeInsets.all(10.0), child: Column( children: [ const Card( child: ListTile( title: Text( "Advice for you !", textAlign: TextAlign.center, ), ), ), Card( child: Column( children: [ ListTile( title: _buildAdviceContent(), ), const SizedBox(height: 5.0), ElevatedButton( onPressed: _isLoading ? null : _fetchAdvice, child: _isLoading ? const SizedBox( width: 20, height: 20, child: CircularProgressIndicator(strokeWidth: 2), ) : const Text("Ghe Advice !"), ), const SizedBox(height: 10), ], ), ), ], ), ), ), ); } // 抽离内容构建逻辑,让代码更清晰 Widget _buildAdviceContent() { if (_isLoading) { return const LinearProgressIndicator(); } else if (_errorMessage != null) { return Text( _errorMessage!, textAlign: TextAlign.center, style: const TextStyle(color: Colors.red), ); } else if (_advice != null) { return Text( _advice!, textAlign: TextAlign.center, ); } else { return const Text("加载中..."); } } }
关键修改说明:
- 新增状态变量:
_advice:存储获取到的建议文本_isLoading:控制加载状态,点击按钮后设为true,请求结束后设为false_errorMessage:存储错误信息,处理网络异常或请求失败的场景
- 重构API方法:
- 将原方法改为
_fetchAdvice(),内部通过setState()更新状态,触发UI刷新 - 添加异常捕获,覆盖网络错误、请求失败等异常情况
- 将原方法改为
- 移除FutureBuilder:
- 直接根据状态变量构建UI,避免每次
build重复发起请求 - 加载状态下按钮设为不可点击,同时替换为小型圆形加载指示器,优化用户体验
- 直接根据状态变量构建UI,避免每次
- 初始化加载:
- 在
initState()中调用_fetchAdvice(),实现页面加载时自动获取第一条建议
- 在
内容的提问来源于stack exchange,提问作者swapnil mane
相关产品推荐
相关产品推荐

