GetMidleware not working on bottomNavigationBar - flutter - GetX
221
BottomNavigationBar (also TabBar) doesn't change routes. It's essentially single page. Therefore route middlewares can't be used with them without complications.
Instead, you can use the auth check on the respective controllers of the views of navigation bar items. A very good place is in the onReady
method of the GetxController
s.
Author by
adian
Updated on January 03, 2023Comments
-
adian over 1 year
i have problem with
GetMidleware
, so i have 3 item inbottomNavigationBar
:- Home
- MyTicket
- Profile
i want user can acces home without login so i put midleware just on
myTicket
andProfile
, but when i click MyTicket or Profile i still can access that and not redirect to login page.this is my midleware 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; } }
this is my appPage 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()], ), ] }
this is my root controller:
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; } } }
and this is my root view where i put my
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, ); } }
-
adian over 2 yearsThank this work for me