How can I navigate to a new screen while closing a Flutter drawer using go_router?

252 Views Asked by At

When navigating in a drawer, the drawer disappears instead of showing the sliding close animation. I'm using go_router and placing a scaffold on every screen.

Is there a way to navigate to a new screen while the drawer is closing? I don't want to use a delay before navigating.

Basic example to reproduce:

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

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

final _navigatorKey = GlobalKey<NavigatorState>();

final GoRouter _router = GoRouter(
  navigatorKey: _navigatorKey,
  routes: <RouteBase>[
    GoRoute(
      path: '/',
      builder: (BuildContext context, GoRouterState state) {
        return const HomeScreen();
      },
      routes: <RouteBase>[
        GoRoute(
          path: 'news',
          builder: (BuildContext context, GoRouterState state) {
            return const NewsScreen();
          },
        ),
      ],
    ),
  ],
);

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

  @override
  Widget build(BuildContext context) {
    return MaterialApp.router(
      routerConfig: _router,
    );
  }
}

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      drawer: const AppDrawer(),
      appBar: AppBar(title: const Text('Home Screen')),
      body: const Center(
        child: Text("Home"),
      ),
    );
  }
}

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      drawer: const AppDrawer(),
      appBar: AppBar(title: const Text('News Screen')),
      body: const Center(
        child: Text("News"),
      ),
    );
  }
}

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

  @override
  Widget build(BuildContext context) {
    return Drawer(
      child: SafeArea(
        child: ListView(
          children: [
            ListTile(
              title: const Text('Home'),
              onTap: () {
                Navigator.pop(context);
                context.go('/');
              },
            ),
            ListTile(
              title: const Text('News'),
              onTap: () {
                Navigator.pop(context);
                context.go('/news');
              },
            ),
          ],
        ),
      ),
    );
  }
}

I tried adding a navigatorKey to the GoRouter but it makes no difference.

1

There are 1 best solutions below

2
On

The default drawer animation duration is Duration(milliseconds: 246);.

To close the drawer you can use Scaffold.of(context).closeDrawer();.

With closing delay animation, it can be

onTap: () async {
  Scaffold.of(context).closeDrawer();
  await Future.delayed(const Duration(milliseconds: 246)); // you can increase the delay if you want
  if (context.mounted) context.go('/');
},