You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.30 17:11:08