I have 4 pages in a GNav() Bottom-Navigation-Bar and I would like to navigate to different page via click of a button.
I am aware that there might be similar questions on stackoverflow already, however I was unable to implement any of them successfully which is why I am posting here as my "last effort".
First off, my Class RootPage() which is where I am defining my GNav bar and the pages linked to each tab.
import 'package:anitan/pages/menu_bar_pages/profile_page.dart';
import 'package:anitan/pages/menu_bar_pages/search_page.dart';
import 'package:anitan/pages/menu_bar_pages/settings_pages/settings_page.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/material.dart';
import 'package:google_nav_bar/google_nav_bar.dart';
import 'home_page.dart';
class RootPage extends StatefulWidget {
RootPage({super.key});
@override
State<RootPage> createState() => _RootPageState();
}
class _RootPageState extends State<RootPage>{
int currentPage = 0;
List<Widget> pages = const [
HomePage(),
ProfilePage(),
SearchPage(),
SettingsPage()
];
final user = FirebaseAuth.instance.currentUser!;
@override
Widget build(BuildContext context) {
return Scaffold(
body: pages[currentPage],
bottomNavigationBar: Container(
color: Colors.green,
child: Padding(
padding:
const EdgeInsets.symmetric(horizontal: 15.0, vertical: 15),
child: GNav(
backgroundColor: Colors.green,
color: Colors.white,
activeColor: Colors.white,
tabBackgroundColor: Colors.green.shade800,
gap: 8,
onTabChange: (index) => setState(() => currentPage = index),
selectedIndex: currentPage,
padding: const EdgeInsets.all(16),
tabs: const [
GButton(icon: Icons.home, text: "Home"),
GButton(icon: Icons.person, text: "My Page"),
GButton(icon: Icons.search, text: "Browse"),
GButton(icon: Icons.settings, text: "Settings"),
],
),
),
),
);
}
}
Next up, the HomePage which has a button. When clicked, I want to change the selected tab of my GNav bar. Pushing the page etc. will lead to the Navigation Bar disappearing which is why this isn’t an option.
import 'package:flutter/material.dart';
class HomePage extends StatefulWidget {
const HomePage({super.key,});
@override
State<HomePage> createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
centerTitle: true,
title: const Text("Home Page"),
automaticallyImplyLeading: false,
leading: IconButton(
onPressed: () {
Navigator.of(context).pop();
},
icon: const Icon(Icons.arrow_back_ios),
),
actions: [
IconButton(
onPressed: () {
debugPrint("appBar Button");
},
icon: const Icon(Icons.info_outline),
),
],
),
body: SafeArea(
child: ElevatedButton(onPressed: (() => print("Change Page Here")), child: Text("Change-Page")),
),
);
}
}
I tried a few things like implementing a StreamController or using a GlobalKey. But I would like to the GNav Bar instead of using a Tab controller because of its design.
In theory, what I am trying to do seems simple:
I would like to currentPage to a new index and call setState() to show the changes.
Can anyone help me understand how I can access change the index and update the selected page in my RootPage?
I have spent 2 days looking into various solutions but I can’t get any of them to work.
Many thanks!
Edit:
Please find the code of my main.dart below.
import 'package:anitan/pages/menu_bar_pages/root_page.dart';
import 'package:flutter/material.dart';
import 'package:firebase_core/firebase_core.dart';
//import 'firebase_options.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp();
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
theme: ThemeData(primarySwatch: Colors.green),
home: RootPage(),
);
}
}
2
Answers
Given the reply from Yeasin Sheikh I implemented a little workaround which seems to be working fine:
First, as recommended by Yeasin, I added a VoidCallback function onTap to my HomePage class:
Then I called this onTap function clicking the button:
In my rootPage class, I then created my HomePage. When the onTap function of that page is being called, I am calling a method to refresh the page (setState) and changing the currentPage index as part of it. This required me to initialize the List of my pages using "late".
To keep everything centralized, I switched to using the same method to update the index in the onTabChange part of the GNav bar as well.
Clicking the button now switches the page. The bottom navigation bar (GNav) will stay on the screen and can be used as usual.
Thank you for your support in figuring this out!
HomePage
is already a part ofRootPage
which is needed to be on the same route.You can use callback method to handle click-event/changing page.Now you will get a callback method while creating
HomePage