GetMidleware 无法在 bottomNavigationBar 上工作 - 抖动 - GetX

GetMidleware not working on bottomNavigationBar - flutter - GetX

我对 GetMidleware 有疑问,所以我在 bottomNavigationBar 中有 3 个项目:

  1. 主页
  2. 我的票
  3. 简介

我希望用户可以在不登录的情况下访问主页,所以我将中间件放在 myTicketProfile 上,但是当我单击 MyTicket 或 Profile 时,我仍然可以访问它而不是重定向到登录页面。

这是我的中间件 class :

class AuthMiddleware extends GetMiddleware {
  final authService = Get.find<AuthService>();

  @override
  RouteSettings? redirect(String? route) {
    if (!authService.currentUser.value.isAuthenticated) {
      Get.log(authService.currentUser.value.isAuthenticated.toString());
      return const RouteSettings(name: Routes.LOGIN);
    }
    return null;
  }
}

这是我的应用程序页面class :

class AppPages {
   
  static const INITIAL = Routes.ROOT;
   static final routes = [

      GetPage(
      name: _Paths.ROOT,
      page: () => const RootView(),
      binding: RootBinding(),
    ),

      GetPage(
      name: _Paths.HOME,
      page: () => const HomeView(),
      binding: RootBinding(),
    ),
      
      GetPage(
      name: _Paths.MYTICKET,
      page: () => const MyTicketView(),
      binding: RootBinding(),
      middlewares: [AuthMiddleware()],
    ),

     GetPage(
      name: _Paths.PROFILE,
      page: () => const ProfileEditView(),
      binding: RootBinding(),
      middlewares: [AuthMiddleware()],
    ),
   ]
}

这是我的根控制器:

class RootController extends GetxController {
  final Rx<String> title = Strings.home.obs;
  final Rx<int> currentIndex = 0.obs;
  final authService = Get.find<AuthService>();

  @override
  void onClose() {
    super.dispose();
  }

  List<Widget> pages = [
    const HomeView(),
    const MyTicketView(),
    const ProfileView(),
    // const BlankView(),
  ];

  //get current page for view
  Widget get currentPage => pages[currentIndex.value];

  //change page when bottom nav item is taped
  Future<void> changePage(int _index) async {
    changeTitle(_index);
    if (Get.currentRoute == Routes.ROOT) {
      await changePageInRoot(_index);
    } else {
      await changePageOutRoot(_index);
    }
  }

  Future changeTitle(int index) async {
    switch (index) {
      case 0:
        title.value = Strings.home;
        break;
      case 1:
        title.value = Strings.myTicket;
        break;
      case 2:
        title.value = Strings.myProfile;
        break;
      default:
    }
  }

  //change page if previously page in root
  Future<void> changePageInRoot(int _index) async {
    currentIndex.value = _index;
    await refreshPage(_index);
  }

  //change page if previously page out of root
  Future<void> changePageOutRoot(int _index) async {
    currentIndex.value = _index;
    await refreshPage(_index);
    await Get.offNamedUntil(Routes.ROOT, (Route route) {
      if (route.settings.name == Routes.ROOT) {
        return true;
      }
      return false;
    }, arguments: _index);
  }
}

//call page by index
Future<void> refreshPage(int _index) async {
  switch (_index) {
    case 0:
      {
        Get.find<HomeController>().onInit();
        break;
      }
    case 1:
      {
        Get.find<MyTicketController>().onInit();
        break;
      }
    case 2:
      {
        Get.find<ProfileController>().onInit();
        // Get.find<BlankController>().onInit();
        break;
      }
  }
}

这是我的根视图,我将 bottomNavigationBar :

class RootView extends GetView<RootController> {
  const RootView({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Obx(
      () => Scaffold(
        appBar: PreferredSize(
          preferredSize: const Size.fromHeight(Dimensions.appBarHeight),
          child: BackWidget(title: controller.title.value),
        ),
        backgroundColor: Colors.white,
        bottomNavigationBar: Material(
          elevation: 10,
          // borderRadius: BorderRadius.circular(20),
          child: BottomNavigationBar(
              selectedIconTheme:
                  const IconThemeData(color: CustomColor.primaryColor),
              selectedLabelStyle: const TextStyle(fontSize: 15),
              selectedItemColor: CustomColor.primaryColor,
              backgroundColor: Colors.white,
              elevation: 25,
              type: BottomNavigationBarType.fixed,
              currentIndex: controller.currentIndex.value,
              onTap: (index) => controller.changePage(index),
              items: [
                bottomNavigationBarItemWidget(
                  'assets/svg/home.svg',
                  Strings.home,
                ),
                bottomNavigationBarItemWidget(
                  'assets/svg/document.svg',
                  Strings.myTicket,
                ),
                bottomNavigationBarItemWidget(
                  'assets/svg/profile.svg',
                  Strings.myProfile,
                ),
              ]),
        ),
        body: controller.currentPage,
      ),
    );
  }

  bottomNavigationBarItemWidget(String icon, String label) {
    return BottomNavigationBarItem(
      icon: SvgPicture.asset(
        icon,
        color: Colors.grey,
        height: 24,
        width: 24,
      ),
      activeIcon: SvgPicture.asset(
        icon,
        color: CustomColor.primaryColor,
        height: 24,
        width: 24,
      ),
      label: label,
      tooltip: label,
    );
  }
}

BottomNavigationBar(也称为 TabBar)不改变路线。它本质上是单页的。因此,路由中间件不能毫无困难地与它们一起使用。 相反,您可以在导航栏项目视图的相应控制器上使用身份验证检查。一个很好的地方是在GetxControlleronReady方法中。