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
相关产品推荐
相关产品推荐

