Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Get.back does not remove route from the stack of initially generated routes using multiple navigators with bottom navigation bar #3203

Open
phawadshah opened this issue Sep 4, 2024 · 0 comments
Assignees

Comments

@phawadshah
Copy link

ATTENTION: DO NOT USE THIS FIELD TO ASK SUPPORT QUESTIONS. USE THE PLATFORM CHANNELS FOR THIS. THIS SPACE IS DEDICATED ONLY FOR BUGS DESCRIPTION.
Fill in the template. Issues that do not respect the model will be closed.

Describe the bug
Using multiple navigators with bottom navigation bar, Get.back works fine when the route is generated through onGenerateRoute but does not work when the routes are generated through onGenerateInitialRoutes.

Reproduction code
NOTE: THIS IS MANDATORY, IF YOUR ISSUE DOES NOT CONTAIN IT, IT WILL BE CLOSED PRELIMINARY)

example:

void main() {
  runApp(
    GetMaterialApp(
      title: "Nested Routing",
      initialRoute: Routes.BASE,
      getPages: [
        GetPage(
          name: Routes.BASE,
          page: () => const BaseView(),
          binding: BaseBinding(),
        ),
      ],
    ),
  );
}

class BaseView extends GetView<BaseController> {
  const BaseView({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Obx(() =>
          controller.widgetOptions.elementAt(controller.selectedIndex.value)),
      bottomNavigationBar: Obx(
        () => BottomNavigationBar(
          type: BottomNavigationBarType.fixed,
          items: const <BottomNavigationBarItem>[
            BottomNavigationBarItem(
              icon: Icon(Icons.home),
              label: 'Home',
            ),
            BottomNavigationBarItem(
              icon: Icon(Icons.person),
              label: 'Profile',
            ),
          ],
          currentIndex: controller.selectedIndex.value,
          onTap: controller.onItemTapped,
        ),
      ),
    );
  }
}

class BaseController extends GetxController {
  static BaseController get to => Get.find<BaseController>();
  RxInt selectedIndex = 0.obs;
  late List<Widget> widgetOptions;

  BaseController() {
    widgetOptions = <Widget>[
      const HomeNavigator(),
      const ProfileWrapper(),
    ];
  }

  void onItemTapped(int index) {
    selectedIndex.value = index;
  }
}

class HomeNavigator extends StatelessWidget {
  const HomeNavigator({
    super.key,
  });
  @override
  Widget build(BuildContext context) {
    Get.put<HomeNavigatorController>(HomeNavigatorController(),
        permanent: true);
    return GetBuilder<HomeNavigatorController>(
      builder: (controller) {
        return Navigator(
          key: Get.nestedKey(nestedNavigationHomeId),
          initialRoute: Routes.HOME,
          onGenerateInitialRoutes: controller.onGenerateInitalRoutes,
          onGenerateRoute: controller.onGenerateRoute,
        );
      },
    );
  }
}

class HomeNavigatorController extends GetxController {
  static HomeNavigatorController get to => Get.find<HomeNavigatorController>();

  // Stack of route names to manage the navigation history
  final List<String> _routeStack = [];

  List<String> get routeStack => _routeStack;

  void pushRoute(String routeName) {
    _routeStack.add(routeName);
  }

  List<Route<dynamic>> get generateRoutes => routeStack.map(
        (route) {
          return GetPageRoute(
            routeName: route,
            page: () {
              switch (route) {
                case Routes.HOME:
                  return const HomeView();
                case Routes.DETAILS:
                  return const DetailsView();
                default:
                  return const HomeView();
              }
            },
            binding: route == Routes.HOME
                ? HomeBinding()
                : route == Routes.DETAILS
                    ? DetailsBindings()
                    : null,
          );
        },
      ).toList();

  List<Route<dynamic>> onGenerateInitalRoutes(
      NavigatorState state, String initialRoute) {
    return routeStack.isNotEmpty
        ? generateRoutes
        : Navigator.defaultGenerateInitialRoutes(state, initialRoute);
  }

  Route<dynamic>? onGenerateRoute(RouteSettings settings) {
    if (settings.name == Routes.HOME) {
      routeStack.add(Routes.HOME);
      return GetPageRoute(
        routeName: Routes.HOME,
        page: () => const HomeView(),
        binding: HomeBinding(),
      );
    }
    if (settings.name == Routes.DETAILS) {
      routeStack.add(Routes.DETAILS);
      return GetPageRoute(
        routeName: Routes.DETAILS,
        page: () => const DetailsView(),
        binding: DetailsBindings(),
      );
    }
    return null;
  }
}

class ProfileWrapper extends StatelessWidget {
  const ProfileWrapper({super.key});

  @override
  Widget build(BuildContext context) {
    return Navigator(
      key: Get.nestedKey(nestedNavigationProfileId),
      initialRoute: Routes.PROFILE,
      onGenerateRoute: (routeSettings) {
        if (routeSettings.name == Routes.PROFILE) {
          return GetPageRoute(
              routeName: Routes.PROFILE,
              title: "Profile Page",
              page: () => const ProfileView(),
              binding: ProfileBinding());
        }
        return null;
      },
    );
  }
}

class HomeView extends GetView<HomeController> {
  const HomeView({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('HomeView'),
        centerTitle: true,
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            TextButton(
              onPressed: controller.goToDetails,
              child: const Text("Go to details"),
            ),
          ],
        ),
      ),
    );
  }
}

class ProfileView extends GetView<ProfileController> {
  const ProfileView({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('ProfileView'),
        centerTitle: true,
      ),
      body: Center(
        child: TextButton(
          onPressed: (){},
          child: const Text("Profile Page"),
        ),
      ),
    );
  }
}

class ProfileController extends GetxController {
  void goToSettingPage() {
  }
}

class HomeController extends GetxController {
  void goToDetails() {
    Get.toNamed(Routes.DETAILS, id: nestedNavigationHomeId);
  }
}

class ProfileBinding extends Bindings {
  @override
  void dependencies() {
    Get.lazyPut<ProfileController>(() => ProfileController());
  }
}

class HomeBinding extends Bindings {
  @override
  void dependencies() {
    Get.lazyPut<HomeController>(() => HomeController());
  }
}

class DetailsView extends GetView<DetailsController> {
  const DetailsView({super.key});
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Details view'),
        centerTitle: true,
        leading: IconButton(
          onPressed: controller.goBack,
          icon: const Icon(Icons.arrow_back),
        ),
      ),
      body: Center(
        child: TextButton(
          onPressed: (){},
          child: TextButton(
            onPressed: controller.goToSearch,
            child: const Text("Details Page"),
          ),
        ),
      ),
    );
  }
}

class DetailsController extends GetxController {
// This is supposed to go through home navigator
  void goBack() {
    Get.back(id: nestedNavigationHomeId);
  }
}

class DetailsBindings extends Bindings {
  @override
  void dependencies() {
    Get.lazyPut<DetailsController>(() => DetailsController());
  }
}

**To Reproduce**
Steps to reproduce the behavior:
1. Go to Details View
2. Change tab to Profile
3. Change tab back to Home
4. Go back
5. Change tab to profile again
6. Change tab back to Home

**Expected behavior**
It is supposed to be on Home Page rather than Details

**Screenshots**
If applicable, add screenshots to help explain your problem.

**Flutter Version:**
3.24.0

**Getx Version:**
get: ^4.6.6

**Describe on which device you found the bug:**
Iphone 15 simulator

**Minimal reproduce code**
Provide a minimum reproduction code for the problem
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants