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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 15:57:52