3

I'm using go_router and I am about to do this in a callback of one of my buttons:

EvelatedButton(
  onPressed: () {
    GoRouter.of(context)
      ..push('/page-1')
      ..push('/page-2');
  },
)

This is to push 2 pages in the history at once. After the user click on this button, he ends up on the page page-2 and when he pops the page, there is page-1.

Is it acceptable to do that or is there any reason not to do it? What would be those reasons and what should I do instead?

I don't think I've seen anything like that in go_router's examples.


For more context, here is a code snippet (or checkout https://github.com/ValentinVignal/flutter_app_stable/tree/go-router/push-twice-at-once):

When the button is pressed, I want to display the dialog page with the page-1 in the background.

import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';

void main() {
  runApp(const MyApp());
}

final router = GoRouter(
  initialLocation: '/page-0',
  routes: [
    GoRoute(
      path: '/page-0',
      builder: (_, __) => const Page0Screen(),
    ),
    GoRoute(
      path: '/page-1',
      builder: (_, __) => const Page1Screen(),
    ),
    GoRoute(
      path: '/dialog',
      pageBuilder: (context, state) => DialogPage(
        key: state.pageKey,
        child: const DialogScreen(),
      ),
    ),
  ],
);

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp.router(
      routerConfig: router,
    );
  }
}

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Page 0')),
      body: Center(
        child: ElevatedButton(
          onPressed: () {
            GoRouter.of(context)
              ..push('/page-1')
              ..push('/dialog');
          },
          child: const Text('Push'),
        ),
      ),
    );
  }
}

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Page 1')),
      body: const Center(
        child: Text('Page 1'),
      ),
    );
  }
}

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

  @override
  Widget build(BuildContext context) {
    return const AlertDialog(
      title: Text('Dialog'),
    );
  }
}

class DialogPage extends Page {
  const DialogPage({
    required this.child,
    super.key,
  });

  final Widget child;

  @override
  Route createRoute(BuildContext context) {
    return DialogRoute(
      settings: this,
      context: context,
      builder: (context) {
        return child;
      },
    );
  }
}

enter image description here

Valentin Vignal
  • 6,151
  • 2
  • 33
  • 73

2 Answers2

1

go_router doesn't support pushing two routes at the same time. And it is not a good practice to push 2 pages at the same time.

What can you do instead?

  1. You can transition from page1 to page2
  2. Go to dialog page in the init method of the page2 using context.go('/dialog');
  3. On exiting dialog page you can use context.pop() which will land you in page1
krishnaacharyaa
  • 14,953
  • 4
  • 49
  • 88
0

Assuming your goal is to display a dialog you can use the showDialog function in flutter.

Below is a sample

showDialog<void>(
      context: context,
      builder: (BuildContext context) {
        return AlertDialog(
          title: const Text('Basic dialog title'),
          content: const Text('A dialog is a type of modal window that\n'
              'appears in front of app content to\n'
              'provide critical information, or prompt\n'
              'for a decision to be made.'),
          actions: <Widget>[
            TextButton(
              style: TextButton.styleFrom(
                textStyle: Theme.of(context).textTheme.labelLarge,
              ),
              child: const Text('Disable'),
              onPressed: () {
                GoRouter.of(context).pop();
              },
            ),
            TextButton(
              style: TextButton.styleFrom(
                textStyle: Theme.of(context).textTheme.labelLarge,
              ),
              child: const Text('Enable'),
              onPressed: () {
                GoRouter.of(context).pop();
              },
            ),
          ],
        );
      },
    );