'Close and recreate controller when navigate through pages using bottom navigation bar on GetX Flutter

I have created bottom navigation bar for 4 pages. Is it possible to make it create the controller only when I tap and close when I navigate to another page?

In my case, I want it to create A's controller only when I tap A page and then when I go to B page, close A page's controller and create the B another page's controller. If I go back to A page, then recreate the A page's controller again.

Just like using Get.offAllNamed(). The reason I want to do this is to reload the page if the stream data inside the page changes especially to Obx() method used in every page.

Also reset any form inside a page if some of its field selected, for example like selecting a value from a dropdown menu and navigate to other page. When navigate back, reset the dropdown back to default.

I put my appbar and bottom nav in separate files and link both files to a pagewrapper.

All 4 pages controller were set on pagewrapper bindings like this:

class PagewrapperBinding extends Bindings {
  @override
  void dependencies() {
    Get.lazyPut<PagewrapperController>(
      () => PagewrapperController(),
    );
    Get.lazyPut<AppbarController>(
      () => AppbarController(),
    );
    Get.lazyPut<SidenavbarController>(
      () => SidenavbarController(),
    );
    Get.lazyPut<HomeController>(
      () => HomeController(),
    );    
    Get.lazyPut<ApplyiptController>(
      () => ApplyiptController(),
    );
    Get.lazyPut<ResultiptController>(
      () => ResultiptController(),
    );
    Get.lazyPut<ProfileController>(
      () => ProfileController(),
    );
  }
}

PageWrapper controller and view:

class PagewrapperController extends GetxController {  
   BottomnavbarController bottomnavbarController =
      Get.put(BottomnavbarController());
      
  final bodyRoutes = [
    const HomeView(),
    const ApplyiptView(),
    const ResultiptView(),
    const ProfileView(),
  ];
}

return Scaffold(
  backgroundColor: Colors.white,
  appBar: const PreferredSize(
    preferredSize: Size.fromHeight(50),
    child: AppbarView(),
  ),
  endDrawer: const SidenavbarView(),
  body: Obx(
    () => Padding(
      padding: const EdgeInsets.only(
        left: 10,
        right: 10,
      ),          
      child: Column(
        children: [
          Expanded(
            child: controller
                .bodyRoutes[controller.bottomnavbarController.bottomNavIndex.value],
          ),
        ],
      ),
    ),
  ),
  bottomNavigationBar: const BottomnavbarView(),
);

my bottom nav controller and view:

class BottomnavbarController extends GetxController {
  var bottomNavIndex = 0.obs;  
}

return Obx(
  () => BottomNavigationBar(
    currentIndex: controller.bottomNavIndex.value,
    onTap: (index) {
      controller.bottomNavIndex.value = index;
    },
    type: BottomNavigationBarType.fixed,
    backgroundColor: Colors.white,
    showSelectedLabels: false,
    showUnselectedLabels: false,
    selectedItemColor: Colors.black87,
    unselectedItemColor: Colors.black38,
    items: const [
      BottomNavigationBarItem(icon: Icon(Icons.home), label: "Home"),
      BottomNavigationBarItem(icon: Icon(Icons.school), label: "Apply IPT"),
      BottomNavigationBarItem(
          icon: Icon(Icons.assignment_sharp), label: "Result IPT"),
      BottomNavigationBarItem(icon: Icon(Icons.person), label: "Profile"),
    ],
  ),
);


Solution 1:[1]

Here is my suggestion to get expected results.

  1. Use IndexedStack to save the state of your screen
  2. Create one common controller on main screen and access the controller on child screen. Use constructor to access that controller.

class ExampleController extends GetxController{
//your code
List<StatelessWidget> screens(ExampleController controller){
    return [AScreen(
    controller: controller,
  ),
  BScreen(
    controller: controller,
  ),
  CScreen(
    controller: controller,
  ),
  DScreen(
    controller: controller,
  ),];
}}

Please check this link. I have written a demo for you. https://pastebin.com/ZassgnJQ

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Bihim