I'm in the process of making a custom navigation bar for my project, and need to pass the current page # from the child navigation bar widget, to the main page. I can't seem to figure out the best method for transferring the int.
Custom navigation bar with int needed to be accessed:
import 'package:flutter/material.dart';
import 'package:my_app/theme.dart';
class CustomNavBar extends StatefulWidget {
const CustomNavBar({Key? key}) : super(key: key);
@override
State<CustomNavBar> createState() => _CustomNavBarState();
}
class _CustomNavBarState extends State<CustomNavBar> {
//Need to pass this int to parent
int currentPage = 0;
@override
Widget build(BuildContext context) {
return Card(
margin: const EdgeInsets.all(0),
shape: const RoundedRectangleBorder(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(24),
topRight: Radius.circular(24),
),
),
color: primaryColor,
child: Row(
children: <Widget>[
Expanded(child: navBarItem(0, Icons.home)),
Expanded(child: navBarItem(1, Icons.looks_one_rounded)),
Expanded(child: navBarItem(2, Icons.looks_two_rounded)),
Expanded(child: navBarItem(3, Icons.looks_3_rounded)),
],
),
);
}
Widget navBarItem(
int index,
IconData icon,
) {
return GestureDetector(
onTap: () {
setState(() {
currentPage = index;
});
},
child: Container(
height: 80,
width: MediaQuery.of(context).size.width / 4,
decoration: const BoxDecoration(
color: Colors.transparent,
),
child: Icon(
icon,
color: index == currentPage ? Colors.white : primaryAccentColor,
),
),
);
}
}
Main.dart where int is needed to be accessed:
import 'package:flutter/material.dart';
import 'package:my_app/Pages/home_page.dart';
import 'package:my_app/Pages/profile_page.dart';
import 'package:my_app/Pages/testing_page.dart';
import 'package:my_app/Pages/testing_page2.dart';
import 'package:my_app/widgets/custom_navbar_widget.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return const MaterialApp(
debugShowCheckedModeBanner: false,
home: RootPage(),
);
}
}
class RootPage extends StatefulWidget {
const RootPage({Key? key}) : super(key: key);
@override
State<RootPage> createState() => _RootPageState();
}
class _RootPageState extends State<RootPage> {
//Replace this int with the one set from CustomNavBar
int currentPage = 0;
List<Widget> pages = [
const HomePage(),
const ProfilePage(),
const TestingPage(),
const TestingPage2(),
];
@override
Widget build(BuildContext context) {
return SafeArea(
top: false,
child: Scaffold(
extendBody: true,
body: pages[currentPage],
bottomNavigationBar: CustomNavBar(),
),
);
}
}
You can use a ValueChange
. Actually, this is a signature for callbacks that report that an underlying value has changed.
Look at the implementation :
typedef ValueChanged<T> = void Function(T value);
Also, you can use it in the child class like this :
import 'package:flutter/material.dart';
import 'package:my_app/theme.dart';
class CustomNavBar extends StatefulWidget {
const CustomNavBar({Key? key, required this.onItemSelect}) : super(key: key);
final ValueChanged<int> onItemSelect;
@override
State<CustomNavBar> createState() => _CustomNavBarState();
}
class _CustomNavBarState extends State<CustomNavBar> {
//Need to pass this int to parent
int currentPage = 0;
@override
Widget build(BuildContext context) {
return Card(
margin: const EdgeInsets.all(0),
shape: const RoundedRectangleBorder(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(24),
topRight: Radius.circular(24),
),
),
color: primaryColor,
child: Row(
children: <Widget>[
Expanded(child: navBarItem(0, Icons.home)),
Expanded(child: navBarItem(1, Icons.looks_one_rounded)),
Expanded(child: navBarItem(2, Icons.looks_two_rounded)),
Expanded(child: navBarItem(3, Icons.looks_3_rounded)),
],
),
);
}
Widget navBarItem(
int index,
IconData icon,
) {
return GestureDetector(
onTap: () {
setState(() {
widget.onItemSelect(currentPage);
currentPage = index;
});
},
child: Container(
height: 80,
width: MediaQuery.of(context).size.width / 4,
decoration: const BoxDecoration(
color: Colors.transparent,
),
child: Icon(
icon,
color: index == currentPage ? Colors.white : primaryAccentColor,
),
),
);
}
}
And check for new changes in parent, like this :
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return const MaterialApp(
debugShowCheckedModeBanner: false,
home: RootPage(),
);
}
}
class RootPage extends StatefulWidget {
const RootPage({Key? key}) : super(key: key);
@override
State<RootPage> createState() => _RootPageState();
}
class _RootPageState extends State<RootPage> {
//Replace this int with the one set from CustomNavBar
int currentPage = 0;
List<Widget> pages = [
const HomePage(),
const ProfilePage(),
const TestingPage(),
const TestingPage2(),
];
@override
Widget build(BuildContext context) {
return SafeArea(
top: false,
child: Scaffold(
extendBody: true,
body: pages[currentPage],
bottomNavigationBar: CustomNavBar(onItemSelect: (value) => print(value),),
),
);
}
}
For more detail, please check : https://api.flutter.dev/flutter/foundation/ValueChanged.html
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.