Dart:对话框后返回上一屏幕,菜单关闭并触发 REST POST

问题描述 投票:0回答:1

我有一个从屏幕底部弹出的子菜单。第三个菜单项是“停用此任务”deactivateThisQuest.tr(),当用户点击它时,它会调用 onsubmit() 函数,该函数有一个带有“取消”和“确定”的弹出对话框,点击“取消”关闭对话框并按预期关闭菜单,点击“确定”将 REST POST 发送回服务器。

我想做的是,当用户在弹出对话框上单击“确定”时,我希望它返回到上一个屏幕。但为了做到这一点,需要关闭对话框,然后关闭我们之前调用的弹出菜单,然后返回到上一个屏幕。

如果我放 3 个“Navigator.pop(context);”在如下所示的一行中,它会按预期转到上一个屏幕,但不会触发 API POST。如果我放 2 个“Navigator.pop(context);”连续,然后对话框和菜单关闭并且 API 触发。如果我放一个“Navigator.pop(context);”在 onRefresh() 之后;当对话框和菜单关闭时,API 会触发,但仍然不会返回到上一个屏幕。

关于如何实现这一目标有什么想法吗?

class QuestMenu extends HookConsumerWidget {
  const QuestMenu(
      {super.key,
      required this.questId,
      required this.questName,
      required this.privateLink,
      required this.onRefresh,
      this.token,
      required this.isJoined,
      required this.isDeactivated});

  final int questId;
  final String questName;
  final String privateLink;
  final String? token;
  final VoidCallback onRefresh;
  final bool isJoined;
  final bool isDeactivated;

  void show(BuildContext context) {
    showModalBottomSheet<void>(
      context: context,
      builder: (_) => QuestMenu(
          questId: questId,
          questName: questName,
          privateLink: privateLink,
          token: token,
          onRefresh: onRefresh,
          isJoined: isJoined,
          isDeactivated: isDeactivated),
      useRootNavigator: true,
      isScrollControlled: true,
      shape: const RoundedRectangleBorder(
        borderRadius: BorderRadius.only(
          topLeft: Radius.circular(16),
          topRight: Radius.circular(16),
        ),
      ),
    );
  }

  @override
  Widget build(BuildContext context, WidgetRef ref) {

    final onSubmit = useCallback(
      () async {
        // Show confirmation dialog
        await showDialog<bool>(
          context: context,
          barrierDismissible: false,
          builder: (BuildContext context) {
            return AlertDialog(
              shape: RoundedRectangleBorder(
                borderRadius: BorderRadius.circular(20),
              ),
              insetPadding: const EdgeInsets.symmetric(
                horizontal: 20,
                vertical: 24,
              ),
              title: Text(
                'deactivateQuest'.tr(),
                style: popupTitle.copyWith(color: Palette.titleColor),
                textAlign: TextAlign.center,
              ),
              content: Text(
                'sureDeactivate'.tr(),
                style: basicText.copyWith(color: Palette.generalText),
                textAlign: TextAlign.justify,
              ),
              actions: [
                Row(
                  mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                  children: [
                    Expanded(
                      child: OutlineButton(
                        label: 'Cancel',
                        onPressed: () {
                          Navigator.pop(context); // Close dialog
                          Navigator.pop(context); // Close menu
                        },
                        //child: Text('Cancel'),
                      ),
                    ),
                    gapW8, // Adjust spacing between buttons
                    Expanded(
                      child: PrimaryButton(
                        label: 'OK',
                        onPressed: () async {
                          Navigator.pop(context); // Close dialog
                          Navigator.pop(context); // Close menu
                          Navigator.pop(context); // Go back to previous screen
                          await ref
                              .read(deactivateQuestNotifierProvider.notifier)
                              .deactivateQuest(questId, token: token);
                          onRefresh();
                          //Navigator.pop(context); // Go back to previous screen
                        },
                        //child: Text('Confirm'),
                      ),
                    ),
                  ],
                ),
              ],
            );
          },
        );
      },
      [],
    );

    return SafeArea(
      top: false,
      child: Padding(
        padding: const EdgeInsets.all(pdMdHorizontal),
        child: Column(
          mainAxisSize: MainAxisSize.min,
          children: [
            _MenuTile(
              label: 'clickView'.tr(),
              icon: SvgPicture.asset(Assets.svg.routeFilled),
              showChevron: true,
              onTap: () {
                launchUrl(url);
              },
            ),
            gapH16,
            _MenuTile(
              label: 'shareWithFriend'.tr(),
              icon: SvgPicture.asset(Assets.svg.share),
              showChevron: true,
              onTap: () => Share.share(privateLink),
            ),
            gapH16,
            if (isJoined && !isDeactivated)
              _MenuTile(
                label: 'deactivateThisQuest'.tr(),
                icon: SvgPicture.asset(Assets.svg.flasher),
                showChevron: true,
                onTap: onSubmit,
              ),
          ],
        ),
      ),
    );
  }
}

class _MenuTile extends StatelessWidget {
  const _MenuTile({
    required this.icon,
    required this.label,
    this.onTap,
    this.showChevron = false,
  });

  final SvgPicture icon;
  final String label;
  final bool showChevron;
  final VoidCallback? onTap;

  @override
  Widget build(BuildContext context) {
    return InkWell(
      onTap: onTap,
      child: Row(
        children: [
          icon,
          gapW10,
          Text(label, style: buttonText.copyWith(color: Palette.activeGreen)),
          if (showChevron) const Spacer(),
          if (showChevron) SvgPicture.asset(Assets.svg.chevronNext),
        ],
      ),
    );
  }
}
flutter dart
1个回答
0
投票

修改 onPressed:

onPressed: () async {
  Navigator.pop(context); // Close dialog
  Navigator.pop(context); // Close menu
  await Future.delayed(Duration(milliseconds: 100)); // Delay for smooth transition (optional)
  Navigator.pop(context); // Go back to previous screen
  await ref
      .read(deactivateQuestNotifierProvider.notifier)
      .deactivateQuest(questId, token: token);
  onRefresh();
},

“Future.delayed”在关闭菜单后持续时间较短,以允许在返回上一屏幕之前平滑过渡

© www.soinside.com 2019 - 2024. All rights reserved.