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

Flutter登录点击时CircularProgressIndicator仅首次显示问题求解

问题根源

你的代码存在两个核心问题导致进度条仅第一次生效:

  • 你的bloc.loginStream没有做状态重置逻辑,第一次请求返回错误/成功后,流的状态会永久保留,后续点击登录按钮时,StreamBuilder会立刻读取到上一次残留的错误/成功状态,直接把isButtonPressed改回false,导致进度条刚触发就被隐藏。
  • 你在StreamBuilder的builder回调中修改状态变量后,没有通过setState同步状态变更到视图,部分场景下状态和视图会出现不一致。

修复方案

步骤1:给bloc添加登录流重置逻辑

在你的bloc类中添加重置loginStream的方法,每次点击登录按钮时先调用重置方法清空上一次的流状态,避免旧状态干扰:

// 在bloc类中添加重置方法,根据你实际使用的流控制器调整实现
void resetLoginStream() {
  // 示例:如果用BehaviorSubject实现loginStream,清空之前的事件即可
  _loginSubject.add(null);
}

步骤2:调整登录按钮点击逻辑

点击按钮时先重置流状态,避免上一次的请求结果残留:

onPressed: () {
  setState(() {
    isButtonPressed = true;
    hasErr = false;
  });
  // 先重置流状态
  bloc.resetLoginStream();
  bloc.login(nameController.text, passwordController.text);
},

步骤3:优化StreamBuilder的状态更新逻辑

所有状态修改统一通过setState触发,避免状态和视图不同步:

builder: (BuildContext context, AsyncSnapshot snapshot) {
  if (snapshot.hasData) {
    WidgetsBinding.instance!.addPostFrameCallback((_) {
      setState(() => isButtonPressed = false);
      Navigator.pushReplacement(
        context, 
        MaterialPageRoute(builder: (_) => HomeScreen())
      );
    });
  } else if (snapshot.hasError) {
    WidgetsBinding.instance!.addPostFrameCallback((_) {
      setState(() {
        isButtonPressed = false;
        hasErr = true;
        errTxt = snapshot.error.toString();
      });
    });
  }
  // 剩余原有布局代码不变
}

内容的提问来源于stack exchange,提问作者imaliveagain

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 15:54:03