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

使用Get.toNamed()跳转页面后首个Dialog失效问题求助

GetMaterialApp中使用Get.toNamed()后第一页Dialog失效问题

关联GitHub Issue #2502,使用GetMaterialApp组件时遇到以下问题:使用Get.toNamed()跳转页面后,返回第一页时原本的首个Dialog功能失效,但使用Navigator.push()则正常,而Web应用必须使用Get.toNamed()。

问题重现流程

  • 第一页按钮打开首个Dialog,Dialog内包含跳转第二页的按钮;
  • 点击Dialog内按钮,通过Get.toNamed()打开第二页;
  • 第二页打开第二个Dialog,操作完成后点击返回回到第一页;
  • 此时第一页的首个Dialog无法正常触发。

代码示例

import 'package:flutter/material.dart';
import 'package:flutter_test_exam_bug/config/path/page_path.dart';
import 'package:get/get.dart';

Future<void> _showMyDialog({required BuildContext context, required Widget child}) async {
  return showDialog<void>(
    context: context,
    builder: (BuildContext context) => child,
  );
}

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

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

class _PageTestState extends State<PageTest> {
  @override
  Widget build(BuildContext context) {
    Widget dialog_ = Center(
            child: ElevatedButton(onPressed: () => Get.toNamed(PagePath.test2), child: const Text("Open second page"))),
        openDialogButton_ = ElevatedButton(
            onPressed: () => _showMyDialog(context: context, child: dialog_), child: const Text("Open first dialog"));

    return Scaffold(body: SafeArea(child: Center(child: openDialogButton_)));
  }
}

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

  @override
  State<PageTest2> createState() => _PageTest2State();
}

class _PageTest2State extends State<PageTest2> {
  ButtonStyle buttonStyle = ElevatedButton.styleFrom(primary: Colors.green);

  @override
  Widget build(BuildContext context) {
    Widget dialog_ = Center(
            child: ElevatedButton(
                onPressed: () => Navigator.pop(context), child: const Text("I am second dialog"), style: buttonStyle)),
        openDialogButton_ = ElevatedButton(
            onPressed: () => _showMyDialog(context: context, child: dialog_),
            child: const Text("Open second dialog"),
            style: buttonStyle);

    return Scaffold(appBar: AppBar(), body: SafeArea(child: Center(child: openDialogButton_)));
  }
}

问题原因及解决方法

问题核心是Dialog的上下文复用冲突:你在第一页build方法中提前创建了dialog_实例,它绑定的是第一页初始的BuildContext;但经过GetX路由跳转后,上下文状态发生变化,后续调用这个预创建的Dialog时,上下文已失效。

修复方案1:延迟创建Dialog实例

不在build方法中预创建Dialog内容,而是在点击按钮时动态生成,确保每次调用showDialog都使用最新的上下文:

@override
Widget build(BuildContext context) {
  final openDialogButton_ = ElevatedButton(
      onPressed: () => _showMyDialog(
            context: context,
            // 点击时才创建Dialog内容,保证上下文有效
            child: Center(
              child: ElevatedButton(
                  onPressed: () => Get.toNamed(PagePath.test2),
                  child: const Text("Open second page")),
            ),
          ),
      child: const Text("Open first dialog"));

  return Scaffold(body: SafeArea(child: Center(child: openDialogButton_)));
}

修复方案2:使用GetX自带的Dialog方法

GetX提供了Get.dialog()方法,会自动管理正确的上下文,避免原生showDialog与GetX路由的冲突:

// 修改Dialog展示方法,无需传入context
Future<void> _showMyDialog({required Widget child}) async {
  return Get.dialog(child);
}

// 调用示例
onPressed: () => _showMyDialog(
  child: Center(
    child: ElevatedButton(
        onPressed: () => Get.toNamed(PagePath.test2),
        child: const Text("Open second page")),
  ),
),

两种方案都能保证路由跳转前后上下文的一致性,解决返回后Dialog失效的问题。

内容的提问来源于stack exchange,提问作者Sittiphan Sittisak

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.22 12:54:23