Minimal code :
import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
MyApp({super.key});
final GoRouter _router = GoRouter(
initialLocation: '/page1',
routes: [
ShellRoute(
builder: (context, state, child) {
return ScaffoldWithNavRail(child: child);
},
routes: [
GoRoute(
path: '/page1',
builder: (context, state) => const PageWithPopupMenu(title: 'Page 1'),
),
GoRoute(
path: '/page2',
builder: (context, state) => const PageWithPopupMenu(title: 'Page 2'),
),
],
),
],
);
@override
Widget build(BuildContext context) {
return MaterialApp.router(
routerConfig: _router,
title: 'Flutter Demo',
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
useMaterial3: true,
),
);
}
}
class ScaffoldWithNavRail extends StatelessWidget {
final Widget child;
const ScaffoldWithNavRail({required this.child, super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
body: Row(
children: <Widget>[
NavigationRail(
selectedIndex: _getSelectedIndex(context),
onDestinationSelected: (int index) {
_onDestinationSelected(context, index);
},
labelType: NavigationRailLabelType.selected,
destinations: const <NavigationRailDestination>[
NavigationRailDestination(
icon: Icon(Icons.looks_one),
selectedIcon: Icon(Icons.looks_one),
label: Text('Page 1'),
),
NavigationRailDestination(
icon: Icon(Icons.looks_two),
selectedIcon: Icon(Icons.looks_two),
label: Text('Page 2'),
),
],
),
const VerticalDivider(thickness: 1, width: 1),
Expanded(child: child),
],
),
);
}
int _getSelectedIndex(BuildContext context) {
final String location = '/page1';
switch (location) {
case '/page1':
return 0;
case '/page2':
return 1;
default:
return 0;
}
}
void _onDestinationSelected(BuildContext context, int index) {
switch (index) {
case 0:
context.go('/page1');
break;
case 1:
context.go('/page2');
break;
}
}
}
class PageWithPopupMenu extends StatelessWidget {
final String title;
const PageWithPopupMenu({required this.title, super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(title),
),
body: PopupMenuButton<String>(
icon: Icon(Icons.more_vert),
onSelected: (String result) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('Selected: $result')),
);
},
itemBuilder: (BuildContext context) => <PopupMenuEntry<String>>[
const PopupMenuItem<String>(
value: 'Item 1',
child: Text('Item 1'),
),
const PopupMenuItem<String>(
value: 'Item 2',
child: Text('Item 2'),
),
const PopupMenuItem<String>(
value: 'Item 3',
child: Text('Item 3'),
),
],
),
);
}
}
So now start the code. Click the dropdown menu. Normally, when you click anywhere outside of the drop-down menu, it closes(its cancelled and oncanceled is called). But here clicks from the NavigationRail() are listened to.When U click on navigation icons .oncanCanlled() isnt called. I want when I click the navigationRail, the dropdown menu is closed and onCanceled() is called and not that I navigate.
Hint: In this example, the program seems to work with a small problem. But in my big app, the DropDwonMenu is kept hanging without its buttons and is not disposed when I navigate.I
Image of how the popupmenu is still hanging in my code :enter image description here.