Flutter点击弹窗确认后修改ElevatedButton文本与颜色
问题根因
你的代码无法实现按钮状态切换,是4个核心错误导致的:
- 枚举初始化非法:
StatusReserva仅包含y/n两个枚举值,StatusReserva()这种写法无法获取合法枚举值,初始状态从根源上错误。 - 状态引用不匹配:按钮渲染时读取的是组件入参
widget.status,但点击确认按钮时修改的是本地State中的status变量,二者完全不打通。 - 状态更新未触发重绘:修改变量时没有包裹
setState,就算本地变量值变了,Flutter也不会重新渲染按钮。 - 逻辑执行失效:
_incrementCount是需要传参调用的函数,你在点击事件里只写了函数名没加括号传参,计数逻辑根本没执行;修改状态后也没有调用父组件传入的onStatusChanged回调,全局状态不会同步,页面重建后状态会直接重置。
修复方案
1. 修正全局初始状态
打开main.dart,找到状态声明位置,把非法的枚举初始化改成默认未预订状态:
// 原错误写法 // StatusReserva status = StatusReserva(); // 修改为 StatusReserva status = StatusReserva.n;
2. 修正子组件初始状态
打开days_of_week_meals_screen.dart,修正本地状态的初始值:
class _DaysOfWeekMealsScreenState extends State<DaysOfWeekMealsScreen> { // 原错误写法 // StatusReserva status = StatusReserva(); // 修改为 StatusReserva status = StatusReserva.n; @override void initState() { super.initState(); status = widget.status; } // ... 其余代码保留 }
3. 修正确认预订按钮的点击逻辑
给_incrementCount补上调用括号,状态修改包裹setState,修改完成后调用父组件回调同步全局状态:
TextButton( child: const Text('Sim'), onPressed: () { _incrementCount(context); // 补括号和参数,实际执行计数逻辑 Navigator.pop(context); setState(() { status = StatusReserva.y; }); widget.onStatusChanged(status); // 同步状态到父组件 }, ),
4. 修正按钮渲染的状态引用,补充取消预订逻辑
把按钮颜色、文本读取的状态源从widget.status替换为本地State的status,同时补充已预订状态下的取消确认逻辑,实现状态双向切换:
Card( shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(15), ), margin: const EdgeInsets.all(10), child: ElevatedButton( onPressed: () { if (status == StatusReserva.n) { _showMyDialog(context); } else { // 已预订状态弹出取消确认框 showDialog<void>( context: context, barrierDismissible: false, builder: (BuildContext context) { return AlertDialog( content: SingleChildScrollView( child: ListBody( children: const <Widget>[ Text( 'Confirmar cancelamento da reserva?', textAlign: TextAlign.center, style: TextStyle( fontSize: 15, fontFamily: 'Raleway', fontWeight: FontWeight.bold), ), ], ), ), actions: <Widget>[ Row( mainAxisAlignment: MainAxisAlignment.end, children: [ TextButton( child: const Text('Sim'), onPressed: () { Navigator.pop(context); setState(() { status = StatusReserva.n; }); widget.onStatusChanged(status); }, ), TextButton( child: const Text('Não'), onPressed: () => Navigator.pop(context), ), ], ), ], ); }, ); } }, style: ButtonStyle( shape: MaterialStateProperty.all(RoundedRectangleBorder( borderRadius: BorderRadius.circular(15), )), padding: MaterialStateProperty.all(const EdgeInsets.all(15)), // 读取本地state的status值 backgroundColor: MaterialStateProperty.all(statusToColor(status)), ), // 读取本地state的status值 child: Text(statusToString(status)), ), ),
改完之后热重载即可生效:初始状态按钮为绿色、显示「Reservar」,点击确认预订后按钮变为红色、显示「Cancelar Reserva」,再次点击可走取消流程切回初始状态。
内容的提问来源于stack exchange,提问作者pedro.curti
相关产品推荐
相关产品推荐

