Nested GetRouterOutlet not working
Describe the bug
Using doubly nested GetRouterOutlet causes the second router to.. disappear? I really have no idea what is happening.
Repo: https://github.com/LuisGMM/get_bug_example
Reproduction code
app_routes.dart
// Remove analyzer from this file
// ignore_for_file: constant_identifier_names
import 'package:project/app_pages.dart';
/// Used to define all the routes in the application.
/// Use it along the `Get.*Named()` methods to navigate to the desired screen.
abstract class AppRoutes {
AppRoutes._();
static const String INIT = HOME;
static const String HOME = AppPaths.HOME;
static const String INVENTORY = AppRoutes.HOME + AppPaths.INVENTORY;
static const SETTINGS = HOME + AppPaths.SETTINGS;
static const SETTINGS_PROFILE = SETTINGS + AppPaths.SETTINGS_PROFILE;
static const SETTINGS_SUPPORT_NOTIFICATION = SETTINGS + AppPaths.SETTINGS_SUPPORT_NOTIFICATION;
}
/// Used to define all the paths in the application.
/// They are not used directly for navigation, but are used to
/// build the routes in the [AppRoutes] class and the pages
/// in the [AppPages] class.
abstract class AppPaths {
AppPaths._();
static const HOME = '/home';
static const INVENTORY = '/inventory';
static const SETTINGS = '/settings';
static const SETTINGS_PROFILE = '/profile';
static const SETTINGS_SUPPORT_NOTIFICATION = '/support-notification';
}
app_pages.dart
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:project/app_routes.dart';
import 'package:project/nav_bar_screen.dart';
import 'package:project/settings_screen.dart';
class AppPages {
AppPages._();
// ignore: constant_identifier_names
static const INITIAL = AppRoutes.HOME;
static final pages = [
GetPage<void>(
participatesInRootNavigator: true,
name: AppPaths.HOME,
page: NavBarScreen.new,
transition: Transition.zoom,
transitionDuration: const Duration(milliseconds: 250),
children: [
GetPage(name: AppPaths.INVENTORY, page: () => const Center(child: Text('inventory'))),
GetPage(
name: AppPaths.SETTINGS,
page: () => const SettingsWrapper(),
children: [
GetPage(name: AppPaths.SETTINGS_PROFILE, page: () => const ProfileTabContent()),
GetPage(
name: AppPaths.SETTINGS_SUPPORT_NOTIFICATION,
page: () => const SupportNotificationTabContent(),
),
],
),
],
),
];
}
nav_bar_screen.dart
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:project/app_routes.dart';
class NavBarScreen extends GetResponsiveView<void> {
NavBarScreen({super.key});
@override
Widget phone() {
return Center(child: Text('phone'));
}
@override
Widget tablet() {
return phone();
}
@override
Widget desktop() {
return GetRouterOutlet.builder(
route: AppRoutes.HOME,
builder: (context) {
return Scaffold(
body: SafeArea(
child: Row(
children: [
IndexedRouteBuilder<void>(
routes: const [AppRoutes.INVENTORY, AppRoutes.SETTINGS],
builder: (context, routes, index) {
final delegate = context.delegate;
return Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
ElevatedButton(
onPressed: () => delegate.toNamed<void>(AppRoutes.INVENTORY),
child: Text('Inventory'),
),
ElevatedButton(
onPressed: () => delegate.toNamed<void>(AppRoutes.SETTINGS),
child: Text('Settings'),
),
],
);
},
),
Expanded(
child: GetRouterOutlet(
initialRoute: AppRoutes.INVENTORY,
anchorRoute: AppRoutes.HOME,
),
),
],
),
),
);
},
);
}
}
settings_screen.dart
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:project/app_routes.dart';
class ProfileTabContent extends StatelessWidget {
const ProfileTabContent({super.key});
@override
Widget build(BuildContext c) => const Center(child: Text('🛠 Profile screen goes here'));
}
class SupportNotificationTabContent extends StatelessWidget {
const SupportNotificationTabContent({super.key});
@override
Widget build(BuildContext c) => const Center(child: Text('🛠 Support & notification prefs'));
}
class SettingsWrapper extends StatefulWidget {
const SettingsWrapper({super.key});
@override
_SettingsWrapperState createState() => _SettingsWrapperState();
}
class _SettingsWrapperState extends State<SettingsWrapper> with SingleTickerProviderStateMixin {
final _routes = [AppRoutes.SETTINGS_PROFILE, AppRoutes.SETTINGS_SUPPORT_NOTIFICATION];
@override
Widget build(BuildContext context) {
return GetRouterOutlet.builder(
route: AppRoutes.SETTINGS,
builder: (context) {
return SafeArea(
child: Scaffold(
bottomNavigationBar: IndexedRouteBuilder<void>(
routes: _routes,
builder: (context, routes, index) {
return ElevatedButton(
onPressed:
() => context.delegate.toNamed<void>(AppRoutes.SETTINGS_SUPPORT_NOTIFICATION),
child: const Text('Wtf is going on?'),
);
},
),
body: GetRouterOutlet(
initialRoute: AppRoutes.SETTINGS_PROFILE,
anchorRoute: AppRoutes.SETTINGS,
),
),
);
},
);
}
}
main.dart
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:project/app_pages.dart';
import 'package:project/nav_bar_screen.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return GetMaterialApp(title: 'Flutter Demo', home: NavBarScreen(), getPages: AppPages.pages);
}
}
To Reproduce Steps to reproduce the behavior:
- Add the code into a GetMaterialApp
- Click on the 'Settings' button
- Click on 'Wtf is going on?'
- The 'Wtf is going on?' disappears
Expected behavior
As with the column of buttons, I expected the bottomNavigationBar to remain in place, instead it disappears and opens the AppRoutes.SETTINGS_SUPPORT_NOTIFICATION in "Full screen" next to the column of buttons.
Screenshots
Go to settings
Here we can see the bottom bar (I tried adding columns & rows to the body too, same result):
However, after clicking on it we see the new page, but the bottom bar wen on holidays :(
Flutter Version: Latest
Getx Version: get: ^5.0.0-release-candidate-9.3.2
Describe on which device you found the bug: ex: settings_screen.dart.
Minimal reproduce code I made a repo with it: https://github.com/LuisGMM/get_bug_example
Note this example also suffers this bug: https://github.com/jonataslaw/getx/issues/3336
Oh and I based this example on the @jonataslaw example:
Another thing, sorry, I tested it on the web, like this: flutter run -d chrome