Flutter使用三元运算符控制按钮启用/禁用时状态不实时更新问题求解
问题原因
- 你在子组件
OnlineBehaviour中调用setState只会触发当前子组件的UI刷新,无法通知父组件Quiz重建。 - 提交按钮的状态判断逻辑写在父组件
Quiz的build方法中,只有父组件触发重建时才会重新读取Score.allQuestionsAnswered的最新值,这就是为什么只有刷新页面后按钮才会生效的原因。
最小改动解决方案
步骤1:给自定义组件新增回调参数
给OnlineBehaviour类新增一个可选的回调参数,用于在最后一题作答完成后通知父组件刷新:
class OnlineBehaviour extends StatefulWidget { final String behaviourQuestion; final String explanation; final bool lastQuestionAnswered; // 新增回调参数 final VoidCallback? onLastQuestionAnswered; bool buttonTapped = false; bool questionsAnswered = false; OnlineBehaviour( this.behaviourQuestion, this.explanation, this.lastQuestionAnswered, // 把回调加入构造函数 this.onLastQuestionAnswered, ); // 其余原有代码保持不变 }
步骤2:修改子组件的激活提交逻辑
在activateSubmitButton方法中,修改完全局变量后触发回调通知父组件:
activateSubmitButton() { setState(() { if (widget.lastQuestionAnswered == true) { Score.allQuestionsAnswered = true; // 触发父组件传入的回调 widget.onLastQuestionAnswered?.call(); } }); }
步骤3:父组件实现回调逻辑
在Quiz的状态类中新增触发自身重建的方法,再把这个方法传给最后一个OnlineBehaviour组件即可:
class _QuizState extends State<Quiz> { // 新增方法,触发父组件UI重建 void _updateSubmitButton() { setState(() {}); } @override Widget build(BuildContext context) { // 其余原有代码保持不变,仅修改最后一个OnlineBehaviour的构造参数 // ... OnlineBehaviour( '10. I accept all terms & conditions of all apps/websites without reading them', 'All of us are guilty for this one because a lot of websites/apps have loads of pages ' 'talking about their conditions when accessing their services. If you ignore these they might' 'use the data stored on you in bad ways such as selling it to other ' 'dodgy companies who might use your data in malicious ways', true, // 传入刷新回调 _updateSubmitButton, ), // 其余原有代码保持不变 } }
额外优化建议
- 不推荐用静态类存储业务状态,后续业务复杂后很容易出现状态不同步的问题,可根据项目规模选用
Provider、Riverpod、Bloc等状态管理方案。 - 不要在
StatefulWidget的定义中存储可变变量(比如你代码里的buttonTapped、questionsAnswered),这些可变状态应该放到对应的State类中存储,避免组件重建时状态丢失。
内容的提问来源于stack exchange,提问作者EnCoder2000
相关产品推荐
相关产品推荐

