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

Flutter中如何在try catch块用Get.off()根据当前页面跳转不同界面

问题描述

我有一个按钮会调用updateAllergy()函数,执行后会跳转至首页。现在希望另一个页面也设置调用该函数的按钮,但两个页面执行后需跳转至不同界面。请问能否根据当前所在页面指定跳转目标?我是Flutter初学者,以下是相关代码:

allergy_controller.dart

class AllergyController extends GetxController {
  static AllergyController get instance => Get.find();

  RxBool isVegan = false.obs;
  RxBool isDairyFree = false.obs;
  RxBool isEgg = false.obs;
  RxBool isNut = false.obs;
  final userController = UserController.instance;
  final userRepository = Get.put(UserRepository());
  GlobalKey<FormState> updateVeganFormKey = GlobalKey<FormState>();
  GlobalKey<FormState> updateDairyFormKey = GlobalKey<FormState>();
  GlobalKey<FormState> updateEggFormKey = GlobalKey<FormState>();
  GlobalKey<FormState> updateNutFormKey = GlobalKey<FormState>();

  // init user data when home appears
  @override
  void onInit() {
    initializeAllergy();
    super.onInit();
  }

  // fetch user record
  Future<void> initializeAllergy() async {
    isVegan.value =
        userController.user.value.preferences['Diet']['IsVegan'] ?? false;
    isDairyFree.value =
        userController.user.value.preferences['Diet']['IsDairyFree'] ?? false;
    isEgg.value =
        userController.user.value.preferences['Allergy']['IsEgg'] ?? false;
    isNut.value =
        userController.user.value.preferences['Allergy']['IsNut'] ?? false;
  }

  void saveVegan(bool? value) {
    isVegan.value = value ?? false;
  }

  void saveDairy(bool? value) {
    isDairyFree.value = value ?? false;
  }

  void saveEgg(bool? value) {
    isEgg.value = value ?? false;
  }

  void saveNut(bool? value) {
    isNut.value = value ?? false;
  }

  Future<void> updateAllergy() async {
    try {
      // form validation
      if (!updateVeganFormKey.currentState!.validate()) {
        updateVeganFormKey.currentState!.save();
        return;
      }

      if (!updateDairyFormKey.currentState!.validate()) {
        updateDairyFormKey.currentState!.save();
        return;
      }

      if (!updateEggFormKey.currentState!.validate()) {
        updateEggFormKey.currentState!.save();
        return;
      }

      if (!updateNutFormKey.currentState!.validate()) {
        updateNutFormKey.currentState!.save();
        return;
      }

      Map<String, dynamic> Preferences = {
        'Allergy': {
          'IsEgg': isEgg.value,
          'IsNut': isNut.value,
        },
        'Diet': {
          'IsVegan': isVegan.value,
          'IsDairyFree': isDairyFree.value,
        },
      };

      // Update the 'isVegan' field within the 'Diet' map
      Preferences['Diet']['IsVegan'] = isVegan.value;
      Preferences['Diet']['IsDairyFree'] = isDairyFree.value;
      Preferences['Diet']['IsEgg'] = isEgg.value;
      Preferences['Diet']['IsNut'] = isNut.value;

      // Create the data to update in Firestore
      Map<String, dynamic> allergyData = {
        'Preferences': Preferences,
      };
      await userRepository.updateSingleField(allergyData);

       // update the rx user value
      userController.user.value.preferences['Diet']['IsVegan'] = isVegan.value;
      userController.user.update((user) {
        user?.preferences['Diet']['IsVegan'] = isVegan.value;
      });

      userController.user.value.preferences['Diet']['IsDairyFree'] =
          isDairyFree.value;
      userController.user.update((user) {
        user?.preferences['Diet']['IsDairyFree'] = isDairyFree.value;
      });

      userController.user.value.preferences['IsEgg'] = isEgg.value;
      userController.user.update((user) {
        user?.preferences['IsEgg'] = isEgg.value;
      });

      userController.user.value.preferences['IsNut'] = isNut.value;
      userController.user.update((user) {
        user?.preferences['IsNut'] = isNut.value;
      });

      // move to previous screen
      Get.off(() => const NavigationMenu());
    } catch (e) {
      NLoaders.errorSnackBar(title: 'Oh Snap!', message: e.toString());
    }
  }
}
解决方案

当然可以实现,给你三种适合初学者的简单方案,基于你使用的GetX框架:

方案一:给updateAllergy添加跳转目标参数

直接修改函数,让它接收一个可选的跳转页面参数,默认值设为原来的首页,不同页面调用时传入对应目标页面即可。

修改后的updateAllergy函数:

// 添加可选参数,默认跳转首页
Future<void> updateAllergy({Widget? targetPage}) async {
  try {
    // 保留原有的表单验证、数据更新逻辑...

    // 使用传入的页面,无传入则用默认首页
    final destination = targetPage ?? const NavigationMenu();
    Get.off(() => destination);
  } catch (e) {
    NLoaders.errorSnackBar(title: 'Oh Snap!', message: e.toString());
  }
}

调用方式:

  • 原页面(跳首页):AllergyController.instance.updateAllergy();
  • 新页面(比如跳设置页):AllergyController.instance.updateAllergy(targetPage: const SettingsPage());

方案二:传递回调函数(更灵活)

如果需要在跳转前执行额外逻辑,或自定义跳转行为,可以传递一个回调函数:

修改后的函数:

Future<void> updateAllergy({VoidCallback? onSuccess}) async {
  try {
    // 保留原有的表单验证、数据更新逻辑...

    // 有回调则执行回调,否则默认跳首页
    if (onSuccess != null) {
      onSuccess();
    } else {
      Get.off(() => const NavigationMenu());
    }
  } catch (e) {
    NLoaders.errorSnackBar(title: 'Oh Snap!', message: e.toString());
  }
}

调用方式:

  • 原页面:AllergyController.instance.updateAllergy();
  • 新页面:AllergyController.instance.updateAllergy(onSuccess: () { Get.off(() => const ProfilePage()); });

方案三:通过当前路由判断(不推荐初学者)

可以获取当前页面的路由名称,根据路由判断跳转目标,但需要给页面设置命名路由,对新手稍复杂:

Future<void> updateAllergy() async {
  try {
    // 保留原有的表单验证、数据更新逻辑...

    // 获取当前路由名称
    final currentRoute = Get.currentRoute;
    if (currentRoute == '/allergy-settings') {
      Get.off(() => const NavigationMenu());
    } else if (currentRoute == '/profile-edit') {
      Get.off(() => const ProfilePage());
    } else {
      Get.off(() => const NavigationMenu());
    }
  } catch (e) {
    NLoaders.errorSnackBar(title: 'Oh Snap!', message: e.toString());
  }
}

额外提示:优化原代码

  1. 冗余的Preferences赋值:初始化Preferences时已经给Allergy和Diet设值,后面重复赋值且错误将IsEgg、IsNut加到Diet中,建议删除重复代码:
Map<String, dynamic> Preferences = {
  'Allergy': {
    'IsEgg': isEgg.value,
    'IsNut': isNut.value,
  },
  'Diet': {
    'IsVegan': isVegan.value,
    'IsDairyFree': isDairyFree.value,
  },
};
// 删除以下四行重复代码
// Preferences['Diet']['IsVegan'] = isVegan.value;
// Preferences['Diet']['IsDairyFree'] = isDairyFree.value;
// Preferences['Diet']['IsEgg'] = isEgg.value;
// Preferences['Diet']['IsNut'] = isNut.value;
  1. 冗余的userController更新:无需先修改user.value再调用update,直接用update方法即可:
// 替换原四组更新代码
userController.user.update((user) {
  if (user != null) {
    user.preferences['Diet']['IsVegan'] = isVegan.value;
    user.preferences['Diet']['IsDairyFree'] = isDairyFree.value;
    user.preferences['Allergy']['IsEgg'] = isEgg.value;
    user.preferences['Allergy']['IsNut'] = isNut.value;
  }
});

内容的提问来源于stack exchange,提问作者Safwan Norasidin

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 08:37:04