Flutter中Dialog内ElevatedButton使用setState无法更新状态如何解决?
问题根因
- 你提供的代码片段中首先没有将变量赋值逻辑包裹在
setState内,未触发组件重绘,你提到的普通页面可正常运行大概率是完整代码中已补充了这部分逻辑。 - 核心原因是Flutter通过
showDialog弹出的弹窗挂载在根路由下,和你的业务页面属于不同的渲染树分支,业务页面调用自身的setState只能刷新自身的UI树,不会触发弹窗的重绘。
解决方法
使用StatefulBuilder包裹弹窗的内部内容,它会提供一个专属于弹窗的状态更新方法,调用该方法即可刷新弹窗内的UI。修改后的实现参考如下:
showDialog( context: context, builder: (dialogContext) { // 弹窗内部状态放在builder作用域内 bool addmaterial = true; return AlertDialog( content: StatefulBuilder( builder: (statefulContext, dialogSetState) { return Column( mainAxisSize: MainAxisSize.min, children: [ ClipRRect( borderRadius: BorderRadius.circular(50), child: SizedBox( height: 40, width: 400, child: ElevatedButton( style: ButtonStyle( backgroundColor: MaterialStateProperty.all<Color>(Color(0xfff4f4f4)), ), onPressed: () { // 调用StatefulBuilder提供的setState更新弹窗状态 dialogSetState(() { addmaterial = !addmaterial; }); }, child: const Text("切换显示状态"), ), ), ), // 你要控制显隐的关联内容 if (addmaterial) const Text("受控显示的内容"), ], ); }, ), ); }, );
注意事项
- 不要将弹窗内部使用的状态变量定义在父页面中,放在
StatefulBuilder的builder作用域内可以避免状态污染 - 更新弹窗状态时必须调用
StatefulBuilder返回的setState实例,调用父页面的setState不会生效
内容的提问来源于stack exchange,提问作者KYflutterrookie
相关产品推荐
相关产品推荐

