Flutter:如何在连接/断开图标按钮间添加加载指示器并实现状态切换?
问题分析与修复方案
你的代码存在三个核心问题,导致状态切换和加载指示器显示异常:
1. 语法逻辑错误:if代码块未正确闭合
原代码中if (state == FlutterVpnState.disconnected)的大括号未闭合就直接编写try块,导致else分支的归属逻辑混乱,断开操作的代码无法正确执行。
2. 加载指示器显示逻辑颠倒
当前代码中icon的判断逻辑是:isPressed为true时显示按钮图片,false时显示加载指示器——这和你想要的"点击时显示加载,完成后显示对应按钮"的需求完全相反。
3. 断开操作未处理异步与状态更新
点击断开按钮时,既没有先设置加载状态,也没有等待disconnect()完成就更新状态,导致加载指示器无法显示,状态切换不生效。
修正后的完整代码
Padding( padding: const EdgeInsets.only(left: 20, right: 20), child: IconButton( onPressed: () async { setState(() { // 点击按钮先显示加载状态 isPressed = true; }); if (state == FlutterVpnState.disconnected) { try { await FlutterVpn.connectIkev2EAP( server: dataAddress, username: _usernameController.text, password: _passwordController.text, ); } catch (e) { // 连接失败也需要关闭加载状态 debugPrint("连接失败: $e"); } } else { await FlutterVpn.disconnect(); } // 无论连接/断开成功或失败,都恢复按钮状态 setState(() { isPressed = false; }); }, icon: isPressed ? const CircularProgressIndicator() // 加载时显示指示器 : Image.asset( state == FlutterVpnState.disconnected ? 'assets/images/power-on.png' : 'assets/images/power-off.png', ), iconSize: 120, ), )
关键修改说明
- 统一在点击按钮时先设置
isPressed = true,确保无论连接还是断开操作都会先显示加载指示器 - 修复
if-else的语法结构,确保分支逻辑正确归属 - 将
icon的判断逻辑颠倒:isPressed为true时显示CircularProgressIndicator,否则根据VPN状态显示对应按钮图片 - 断开操作添加
await,等待断开完成后再更新状态 - 统一在操作完成(无论成功失败)后设置
isPressed = false,恢复按钮显示
内容的提问来源于stack exchange,提问作者rurjaf
相关产品推荐
相关产品推荐

