Milad-Akarie / auto_route_library

Flutter route generator
MIT License
1.52k stars 383 forks source link

Pushing to sub-page in another tab and maintaining history? #1966

Open StefanGilligan opened 1 month ago

StefanGilligan commented 1 month ago

I have two tabs: Home and Books. Each can have sub-pages (e.g. Books tab has individual books as pages).

I would very much like to be able to push an individual book page onto the stack from the Home screen. I would then expect the back button to take me back to the Home screen.

Here's my AppRouter:

@AutoRouterConfig()
class AppRouter extends $AppRouter {
  @override
  List<AutoRoute> get routes => [
        AutoRoute(
          path: '/',
          page: RootRoute.page,
          initial: true,
          children: [
            AutoRoute(
              path: 'home',
              page: HomeScreenProxyRoute.page,
              children: [
                AutoRoute(
                  path: '',
                  page: HomeRoute.page,
                ),
              ],
            ),
            AutoRoute(
              path: 'books',
              page: BooksScreenProxyRoute.page,
              children: [
                AutoRoute(path: '', page: BooksRoute.page),
                AutoRoute(path: ':id', page: BookRoute.page),
              ],
            ),
          ],
        ),
      ];
}

@RoutePage(name: 'HomeScreenProxyRoute')
class HomeScreenProxy extends AutoRouter {
  const HomeScreenProxy({super.key});
}

@RoutePage(name: 'BooksScreenProxyRoute')
class BooksScreenProxy extends AutoRouter {
  const BooksScreenProxy({super.key});
}

Here's my HomeScreen:

@RoutePage()
class HomeScreen extends StatelessWidget {
  const HomeScreen({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(),
      body: Center(
        child: Column(
          children: [
            const Text("HOME"),
            FilledButton(
              onPressed: () {
                // FlutterError (Failed to navigate to BookRoute)
                // context.pushRoute(BookRoute(bookId: "test"));

                // Successfully navigates to individual book, but loses all history therefore no back button.
                AutoRouter.of(context).pushNamed('/books/test');

                // Successfully navigates to individual book, but back button goes to 'Books' tab.
                // AutoRouter.of(context).pushNamed('/books/test', includePrefixMatches: true);
              },
              child: const Text("go to a individual book"),
            ),
          ],
        ),
      ),
    );
  }
}

context.pushRoute(BookRoute(bookId: "test")); won't work (Failed to navigate to BookRoute)

AutoRouter.of(context).pushNamed('/books/test') navigates to the book screen, but there's no back button.

AutoRouter.of(context).pushNamed('/books/test', includePrefixMatches: true) navigates to the book screen but the back button goes to the 'Books' tab rather than back to the 'Home' screen.

Milad-Akarie commented 1 month ago

Use navigate and navigateNamed instead of push

StefanGilligan commented 1 month ago

Same issues unfortunately.

context.navigateTo(BookRoute(bookId: "test")); FlutterError (Failed to navigate to BookRoute)

AutoRouter.of(context).navigateNamed('/books/test') Navigates to the book page but loses all history.

AutoRouter.of(context).navigateNamed('/books/test', includePrefixMatches: true) Navigates to the book page but pressing 'back' goes to the 'Books' page rather than the 'Home' screen

I'm trying to achieve the flow: On Home screen -> press button to go to individual book which is in a separate tab -> press back to go to the Home screen

cavin-7span commented 1 month ago

@StefanGilligan were able to do it?

StefanGilligan commented 1 month ago

@StefanGilligan were able to do it?

Unfortunately not

gasaichandesu commented 1 month ago

For this case your route structure might look like this:

@AutoRouterConfig()
class AppRouter extends $AppRouter {
  @override
  List<AutoRoute> get routes => [
        AutoRoute(
          path: '/',
          page: RootRoute.page,
          initial: true,
          children: [
            AutoRoute(
              path: 'home',
              page: HomeScreenProxyRoute.page,
              children: [
                AutoRoute(
                  path: '',
                  page: HomeRoute.page,
                ),
              ],
            ),
            AutoRoute(
              path: 'books',
              page: BooksScreenProxyRoute.page,
              children: [
                  AutoRoute(path: '', page: BooksRoute.page),
              ],
            ),
          ],

          AutoRoute(path: 'books/:id', page: BookRoute.page),
        ),
      ];
}

With your implementation when BookRoute is pushed router stack would be RootRoute -> BooksScreen -> BookRoute. With this implementation router stack is RootRoute -> BookRoute whether it is pushed from HomeScreen or from BooksScreen