Skip to content

Instantly share code, notes, and snippets.

@eduardoflorence
Created March 23, 2021 19:12
Show Gist options
  • Star 20 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save eduardoflorence/11c0a4db3cba9d50ba72a0c6c262df40 to your computer and use it in GitHub Desktop.
Save eduardoflorence/11c0a4db3cba9d50ba72a0c6c262df40 to your computer and use it in GitHub Desktop.
GetX - Sample BottomNavigationBar
import 'package:flutter/material.dart';
import 'package:get/get.dart';
void main() {
runApp(GetMaterialApp(
debugShowCheckedModeBanner: false,
initialRoute: '/home',
defaultTransition: Transition.fade,
getPages: [
GetPage(
name: '/home',
page: () => HomePage(),
binding: HomeBinding(),
),
GetPage(
name: '/another',
page: () => AnotherPage(),
),
],
));
}
class HomeBinding extends Bindings {
@override
void dependencies() {
Get.lazyPut(() => HomeController());
}
}
class HomeController extends GetxController {
static HomeController get to => Get.find();
var currentIndex = 0.obs;
final pages = <String>['/browse', '/history', '/settings'];
void changePage(int index) {
currentIndex.value = index;
Get.toNamed(pages[index], id: 1);
}
Route? onGenerateRoute(RouteSettings settings) {
if (settings.name == '/browse')
return GetPageRoute(
settings: settings,
page: () => BrowsePage(),
binding: BrowseBinding(),
);
if (settings.name == '/history')
return GetPageRoute(
settings: settings,
page: () => HistoryPage(),
binding: HistoryBinding(),
);
if (settings.name == '/settings')
return GetPageRoute(
settings: settings,
page: () => SettingsPage(),
binding: SettingsBinding(),
);
return null;
}
}
class HomePage extends GetView<HomeController> {
@override
Widget build(BuildContext context) {
return Scaffold(
body: Navigator(
key: Get.nestedKey(1),
initialRoute: '/browse',
onGenerateRoute: controller.onGenerateRoute,
),
bottomNavigationBar: Obx(
() => BottomNavigationBar(
items: const <BottomNavigationBarItem>[
BottomNavigationBarItem(
icon: Icon(Icons.search),
label: 'Browse',
),
BottomNavigationBarItem(
icon: Icon(Icons.history),
label: 'History',
),
BottomNavigationBarItem(
icon: Icon(Icons.settings),
label: 'Settings',
),
],
currentIndex: controller.currentIndex.value,
selectedItemColor: Colors.pink,
onTap: controller.changePage,
),
),
);
}
}
class BrowsePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('Browse')),
body: Center(
child: Container(
child: Text(Get.find<BrowseController>().title.value),
),
),
);
}
}
class HistoryPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('History')),
body: Center(
child: Container(
child: Text(Get.find<HistoryController>().title.value),
),
),
);
}
}
class SettingsPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('Settings')),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
child: Text(Get.find<SettingsController>().title.value),
),
ElevatedButton(
child: Text('Another Page'),
onPressed: () => Get.toNamed('/another'),
),
],
),
),
);
}
}
class BrowseController extends GetxController {
final title = 'Browser'.obs;
}
class HistoryController extends GetxController {
final title = 'History'.obs;
}
class SettingsController extends GetxController {
final title = 'Settings'.obs;
}
class BrowseBinding extends Bindings {
@override
void dependencies() {
Get.lazyPut(() => BrowseController());
}
}
class HistoryBinding extends Bindings {
@override
void dependencies() {
Get.lazyPut(() => HistoryController());
}
}
class SettingsBinding extends Bindings {
@override
void dependencies() {
Get.lazyPut(() => SettingsController());
}
}
class AnotherPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('Another Page')), body: Container());
}
}
@tva77
Copy link

tva77 commented Feb 9, 2022

in case you change line 144 to:
onPressed: () => Get.toNamed('/another', id: 1),
would it persist the bottom nav bar?

I'm trying to implement a Getx persistent bottom navigation bar, and pass arguments to details pages... but all the examples won't work with this nestedkey argument in the Get.toNamed()...
seem to be a Getx bug?

@FarhanSajid1
Copy link

This doesn't seem to delete any controllers in memory that are used

@jackrow
Copy link

jackrow commented Jul 19, 2022

That doesn't look very good

@papalardo
Copy link

Changing L39 with:

    Get.offNamedUntil(
      pages[index],
      (page) => page.settings.name == '/home',
      id: 1,
    );

works to me for disposing previous bindings.

Good solution, thanks bro.

@Abolfazl-MI
Copy link

Hi ,first I should say thanks for providing good example,
then I had little bit confused how to apply this on my project .
In our project we have costume navigation bar which we had created it with Stack and IndexedStack. I dont know what should I really do!
I had made same as you write here in my home controller but throws me 'package:flutter/src/widgets/framework.dart': Failed assertion: line 5026 pos 12: 'child == _child': is not true. error . I don't really know what to do

@Coder7777
Copy link

Coder7777 commented Oct 18, 2023

This code can implement nested navigation very well, but I can not work with GetX middleware together.

For example, route '/history', sometimes needs to attach a token to the request to pull data, if the token does not exist, the App will pop up the login page to ask for login.

Do you have any idea how to make middleware take effect?

// VerifyTokenMiddleware will never be triggered
 return GetPageRoute(
        settings: settings,
        page: () => HistoryPage(),
        binding: HistoryBinding(),
        middleware: [ VerifyTokenMiddleware() ]
      );

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment