setstate 不适用于 showdialog 和 alertdialog

setstate doesn't work with showdialog and alertdialog

使用 stateful 小部件和 setstate 以及 showdialogalertdialog 在我的代码中似乎无法正常工作,但为了简化,我在这里用更小更简单的代码模拟了同样的问题,以便更多地理解问题

import 'package:flutter/material.dart';
import '../widgets/app_drawer.dart';

class Test extends StatefulWidget {

  @override
  State<Test> createState() => _TestState();
}

class _TestState extends State<Test> {

  int x = 0;
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      drawer: AppDrawer(),
      appBar: AppBar(
        title: Text("Shop"),
      ),
      body: Column(
        children: [
          RaisedButton(
            onPressed: () {
              showDialog(
                context: context,
                builder: (ctx) => AlertDialog(
                  title: Text("hey"),
                  content: Text(x.toString()),
                  actions: [
                    RaisedButton(
                      onPressed: () {},
                      child: Text("click me"),
                    ),
                    RaisedButton(
                      onPressed: () {
                        setState(() {
                          x++;
                        });
                      },
                      child: Text("increment"),
                    )
                  ],
                ),
              );
            },
            child: Text("Click"),
          ),
          Text(x.toString()),
        ],
      ),
    );
  }
}

如果你 运行 这段代码你会注意到数字在后台增加但不是在弹出对话框中,要看到更改你必须关闭对话框并重新打开它才能看到最新值 实际代码(非简化版)基于相同的想法但略有不同

这个想法是基于一个商店订单,在该订单中您会看到带有产品的购物车,当您点击编辑购物车产品时,会出现一个弹出对话框,其中包含产品的先前值,您可以从购物车中删除或添加产品,然后点击在更新按钮上。 如果产品列表不为空,则按钮的 onPressed 值可以是批准新购物车的功能,如果您从购物车中删除所有产品,则可以为空(禁用按钮),但它似乎没有立即工作。 按钮看起来像这样

RaisedButton(
  onPressed: orderCart.isEmpty
  ? null
  : () {
       //Function here
    },
  child: Text(
       "Update",
      ),
  ),

您应该在 showDialog 中使用 StatefulBuilder 来使用 setState((){});

...
body: Column(
  children: [
    RaisedButton(
      onPressed: () {
        showDialog(
          context: context,
          builder: (BuildContext context) {
            return StatefulBuilder(
              builder: (context, StateSetter setState) {
                return AlertDialog( 
...