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

Flutter AlertDialog点击按钮后重复弹出问题求助

问题解决:对话框重复弹出的问题

问题根源

你在build方法里通过Future.delayed(Duration.zero, () => _navigateSlide(context))调用对话框,而每次执行setState(比如点击选项切换check状态时)都会触发组件重建,build方法会再次执行,导致对话框被重复调用弹出。

解决方案

把对话框的初始化调用移到initState方法中,因为initState只会在StatefulWidget初始化时执行一次,不会在组件重建时重复触发。同时调整对话框内的逻辑,让Navigator.pop在状态更新后执行,避免顺序冲突。

修改后的完整代码

class ExploreAds extends StatefulWidget {
  ExploreAds({Key? key}) : super(key: key);

  @override
  _ExploreAds createState() => _ExploreAds();
}

class _ExploreAds extends State<ExploreAds> {
  bool show = false;
  bool check1 = false;
  bool check2 = false;
  bool check3 = false;
  bool check4 = false;

  final List<String> data = <String>[];

  void addValue(txt) {
    setState(() {
      data.add('${txt}');
    });
    print(data);
  }

  void removeValue(rmtxt) {
    setState(() {
      data.remove('${rmtxt}');
    });
    print(data);
  }

  @override
  void initState() {
    super.initState();
    // 移到initState,仅在组件初始化时执行一次
    Future.delayed(Duration.zero, () => _navigateSlide(context));
  }

  void _navigateSlide(BuildContext context) {
    final Size size = MediaQuery.of(context).size;
    showDialog(
        context: context,
        builder: (BuildContext context) {
          return AlertDialog(
              content: Container(
            height: 550,
            child: Column(
              crossAxisAlignment: CrossAxisAlignment.end,
              children: [
                SizedBox(height: 10),
                Expanded(
                  child: Container(
                    child: GridView(
                        padding: EdgeInsets.only(right: 8),
                        gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
                          crossAxisCount: 2,
                          crossAxisSpacing: 20,
                          mainAxisSpacing: 20,
                          childAspectRatio: 0.70,
                        ),
                        children: <Widget>[
                          Stack(
                            children: [
                              Container(
                                padding: EdgeInsets.only(right: 5, left: 5),
                                decoration: BoxDecoration(
                                  borderRadius: BorderRadius.circular(10),
                                  border: Border.all(color: Color(0xffacacac)),
                                ),
                                child: InkWell(
                                    onTap: () {
                                      setState(() {
                                        check1 = !check1;
                                        check1 ? addValue('Washing machine') : removeValue('Washing machine');
                                      });
                                      Navigator.pop(context);
                                    },
                                    child: Column(
                                      children: [
                                        Image.asset('assets/icons/pngwing44.png', width: 115, height: 115),
                                        Text('Washing machine')
                                      ],
                                    )
                                ),
                              ),
                              Visibility(
                                  visible: check1,
                                  child: Positioned(
                                    top: 5,
                                    right: 5,
                                    child: Image.asset('assets/icons/tick.png', width: 15),
                                  )
                              )
                            ],
                          ),
                          Stack(
                            children: [
                              Container(
                                padding: EdgeInsets.only(right: 5, left: 5),
                                decoration: BoxDecoration(
                                  borderRadius: BorderRadius.circular(10),
                                  border: Border.all(color: Color(0xffacacac)),
                                ),
                                child: InkWell(
                                    onTap: () {
                                      setState(() {
                                        check2 = !check2;
                                        check2 ? addValue('Air Conditioner') : removeValue('Air Conditioner');
                                      });
                                      Navigator.pop(context);
                                    },
                                    child: Column(
                                      children: [
                                        Image.asset('assets/icons/pngwing45.png', width: 115, height: 115),
                                        Text('Air Conditioner')
                                      ],
                                    )
                                ),
                              ),
                              Visibility(
                                  visible: check2,
                                  child: Positioned(
                                    top: 5,
                                    right: 5,
                                    child: Image.asset('assets/icons/tick.png', width: 15),
                                  )
                              )
                            ],
                          ),
                          Stack(
                            children: [
                              Container(
                                padding: EdgeInsets.only(right: 5, left: 5),
                                decoration: BoxDecoration(
                                  borderRadius: BorderRadius.circular(10),
                                  border: Border.all(color: Color(0xffacacac)),
                                ),
                                child: InkWell(
                                    onTap: () {
                                      setState(() {
                                        check3 = !check3;
                                        check3 ? addValue('Microwave') : removeValue('Microwave');
                                      });
                                      Navigator.pop(context);
                                    },
                                    child: Column(
                                      children: [
                                        Image.asset('assets/icons/pngwing45.png', width: 115, height: 115),
                                        Text('Microwave')
                                      ],
                                    )
                                ),
                              ),
                              Visibility(
                                  visible: check3,
                                  child: Positioned(
                                    top: 5,
                                    right: 5,
                                    child: Image.asset('assets/icons/tick.png', width: 15),
                                  )
                              )
                            ],
                          ),
                          Stack(
                            children: [
                              Container(
                                padding: EdgeInsets.only(right: 5, left: 5),
                                decoration: BoxDecoration(
                                  borderRadius: BorderRadius.circular(10),
                                  border: Border.all(color: Color(0xffacacac)),
                                ),
                                child: InkWell(
                                    onTap: () {
                                      setState(() {
                                        check4 = !check4;
                                        check4 ? addValue('Refrigerators') : removeValue('Refrigerators');
                                      });
                                      Navigator.pop(context);
                                    },
                                    child: Column(
                                      children: [
                                        Image.asset('assets/icons/pngwing46.png', width: 115, height: 115),
                                        Text('Refrigerators')
                                      ],
                                    )
                                ),
                              ),
                              Visibility(
                                  visible: check4,
                                  child: Positioned(
                                    top: 5,
                                    right: 5,
                                    child: Image.asset('assets/icons/tick.png', width: 15),
                                  )
                              )
                            ],
                          ),
                        ]
                    ),
                  ),
                ),
                SizedBox(height: 10),
                Padding(
                  padding: EdgeInsets.fromLTRB(20, 0, 20, 0),
                  child: ElevatedButton(
                    onPressed: () => Navigator.pop(context),
                    style: ElevatedButton.styleFrom(
                      elevation: 6,
                      shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(80.0)),
                      padding: const EdgeInsets.all(0.0),
                    ),
                    child: Container(
                      constraints: const BoxConstraints(minWidth: 88.0, minHeight: 50.0),
                      alignment: Alignment.center,
                      child: const Text(
                        'Apply',
                        textAlign: TextAlign.center,
                        style: TextStyle(
                          color: Colors.white,
                          fontSize: 20,
                        ),
                      ),
                    ),
                  ),
                )
              ],
            )
          )
          );
        });
  }

  @override
  Widget build(BuildContext context) {
    final Size size = MediaQuery.of(context).size;
    final ThemeData themeData = Theme.of(context);
    const double padding = 25;
    const sidePadding = EdgeInsets.symmetric(horizontal: padding);

    return Scaffold(
      body: Container(
          padding: sidePadding,
          width: size.width,
          height: size.height,
          child: Text('$data')
      ),
    );
  }
}

额外优化点

  • 替换自定义的addVerticalSpace为标准组件SizedBox(height:10),避免依赖未定义的工具方法
  • 将Navigator.pop从setState回调中移出,确保状态更新完成后再关闭对话框,逻辑更清晰
  • 简化Visibility的条件判断,check1 ? true : false直接写成check1即可

内容的提问来源于stack exchange,提问作者RAF Algowid

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 02:01:09