Flutter AutoTabsRoute.pageview child not changes (auto_route) - flutter

I'm using the auto_route package for routing in my app. I want to use the AutoTabsRoute.pageview widget to create Scaffold with routing tabs.
I don't know why, but the builder should return a different child each time, but it produces the same child. For that reason, the selected tab changes, while the body does not.
Here is my code:
return AutoTabsRouter.pageView(
routes: const [
MainRoute(),
MaintenanceRoute(),
PaymentsRoute(),
],
builder: (context, child, _) {
return Scaffold(
appBar: AppBar(
title: Text(context.topRoute.name),
leading: const AutoLeadingButton(),
),
body: child,
bottomNavigationBar: BottomNavigationBar(
currentIndex: currentIndex,
onTap: (index) =>
context.read<MenuCubit>().setTab(MenuTabs.values[index]),
items: const [
BottomNavigationBarItem(
label: 'Main',
icon: Icon(Icons.home),
),
BottomNavigationBarItem(
label: 'Maintenance',
icon: Icon(Icons.work),
),
BottomNavigationBarItem(
label: 'Payment',
icon: Icon(Icons.payment),
),
],
),
);
},
);
Why is that happening?

Issue solved!
If you want the child parameter to change, you have to config:
final tabsRouter = AutoTabsRouter.of(context);
inside the builder, and update the index using it only:
onTap: tabsRouter.setActiveIndex
Full example:
return AutoTabsRouter.pageView(
routes: const [
MainRoute(),
MaintenanceRoute(),
PaymentsRoute(),
],
builder: (context, child, _) {
final tabsRouter = AutoTabsRouter.of(context); // <--- configure the AutoTabsRouter parameter
return Scaffold(
appBar: AppBar(
title: const Text('Home365'),
actions: [
IconButton(
onPressed: () {},
icon: const Icon(Icons.notifications_none),
)
],
),
body: child,
bottomNavigationBar: BottomNavigationBar(
currentIndex: tabsRouter.activeIndex, <--- use it here
onTap: tabsRouter.setActiveIndex, <--- use it here
items: const [
BottomNavigationBarItem(
label: 'Main',
icon: Icon(Icons.home),
),
BottomNavigationBarItem(
label: 'Maintenance',
icon: Icon(Icons.work),
),
BottomNavigationBarItem(
label: 'Payment',
icon: Icon(Icons.payment),
),
],
),
);
},
);

Related

how to do page switching and active bottom navigation at the same time?

#overrideWidget build(BuildContext context) {
final PageController controller = PageController();
return Scaffold(
body: SafeArea(
child: PageView(
controller: controller,
children: const [
Center(
child: Text("Page 0"),
),
Center(
child: Text("Page 1"),
)
],
),
),
bottomNavigationBar: BlocListener<MenuBloc, MenuState>(
listener: (context, state) {
controller.jumpToPage(state.index);
},
child: BlocBuilder<MenuBloc, MenuState>(
builder: (context, state) {
return BottomNavigationBar(
items: <BottomNavigationBarItem>[
BottomNavigationBarItem(
icon: const Icon(Icons.explore),
label: state.index.toString(),
),
BottomNavigationBarItem(
icon: const Icon(Icons.apps),
label: state.index.toString(),
),
],
onTap: (index) =>
context.read<MenuBloc>().add(MenuSwitch(state.index)),
selectedItemColor: Colors.black,
);
},
),
),
);
}
i want both? how to make it work properly when the selected item is active and changing pages?
Blockquote
how to do page switching and active bottom navigation at the same time?
It's Worked, With A Little Observation I finally realized it returns index doesn't need state anymore :)

Flutter bottom Navigation bar with Routes

I want to navigate through pages using routes and Navigator.pushNamed() on a Bottom Navigation Bar. Here, I'm using a FlashyTab bar for aesthetics. To be more specific, pressing each of the icons on the navigation bar should take me to a different page, and I want to implement this using routes.
#override
Widget build(BuildContext context) {
Size size = MediaQuery.of(context).size;
return Scaffold(
bottomNavigationBar: FlashyTabBar(
animationCurve: Curves.linear,
selectedIndex: _selectedIndex,
showElevation: true,
onItemSelected: (index) => setState(() {
_selectedIndex = index;
}),
items: [
FlashyTabBarItem(
icon: const Icon(Icons.account_box),
title: const Text('Challenger'),
),
FlashyTabBarItem(
icon: const Icon(Icons.phone),
title: const Text('Contact'),
),
FlashyTabBarItem(
icon: const Icon(Icons.dashboard_rounded),
title: const Text('Events'),
),
FlashyTabBarItem(
icon: const Icon(Icons.badge),
title: const Text('Quick Scan'),
),
],
),
body:
);
}
In your screen define this
List<Widget> pageList = [
const ChallengerScreen(),
const ContactScreen(),
const EventsScreen(),
const QuickScanScreen(),
];
In body use it like this
return Scaffold(
bottomNavigationBar: FlashyTabBar(
animationCurve: Curves.linear,
selectedIndex: _selectedIndex,
showElevation: true,
onItemSelected: (index) => setState(() {
_selectedIndex = index;
}),
items: [
FlashyTabBarItem(
icon: const Icon(Icons.account_box),
title: const Text('Challenger'),
),
FlashyTabBarItem(
icon: const Icon(Icons.phone),
title: const Text('Contact'),
),
FlashyTabBarItem(
icon: const Icon(Icons.dashboard_rounded),
title: const Text('Events'),
),
FlashyTabBarItem(
icon: const Icon(Icons.badge),
title: const Text('Quick Scan'),
),
],
),
//you have to just do changes here...
body:pageList.elementAt(_selectedIndex)
);
You don't need to use Navigator.pushNamed() it not the right method to do.

Flutter, how to change current tab bar view or page or index from child

I have a BottomNavigationBar
import 'screen_one.dart' as screen_one;
import 'screen_two.dart' as screen_two;
List<Widget> _widgetOptions = <Widget>[
screen_one.ScreenOne(),
screen_two.ScreenTwo(),
];
void _onItemTapped(int index) {
setState(() {
_selectedIndex = index;
});
}
Scaffold(
bottomNavigationBar:
BottomNavigationBar(
backgroundColor: Colors.green,
items: const <BottomNavigationBarItem>[
BottomNavigationBarItem(
backgroundColor: Colors.green,
icon: Icon(Icons.person),
title: Text(''),
),
BottomNavigationBarItem(
icon: Icon(Icons.person),
title: Text(''),
),
],
currentIndex: _selectedIndex,
onTap: _onItemTapped,
),
body: _widgetOptions.elementAt(_selectedIndex),
),
I want to change current tab index from children class (ScreenOne, ScreenTwo).
when a function occurs in ScreenOne, it needs to move on to ScreenTwo.
how could I acheive this?
Using callbacks,
Pass _onItemTapped as parameter to ScreenOne() : ScreenOne(_onItemTapped)
Inside ScreenOne : final Function(int) onItemTapped;
cCall onItemTapped(your_index_here)

Page started at begin when navigate between 2 screen using BottomTabNavigator

I am new at Flutter. I started a new project regarding social media. I used BottomTabNavigation for navigating the Home screen to the notification screen. Now the problem is that when I am showing feeds on the home page and I scroll down at many posts. let's say I am on post number 50. Now when I click on the notification and again click on the Home page its started from begin. I need to stay my scroll at a previous position on every main screen.
Here is my code for navigating one page to another.
class _DefaultLayoutWidgetState extends State<DefaultLayoutWidget> {
final List<Map<String, dynamic>> _pages = [
{'page': PostScreen(), 'title': 'SelfieCorner'},
{'page': NotificationScreen(), 'title': 'Notifications'}
];
int _curruntIndex = 0;
void handleTapEvent(inx) {
setState(() {
_curruntIndex = inx;
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: PostAppBarWidget(),
body: _pages[_curruntIndex]['page'],
bottomNavigationBar: BottomNavigationBar(
onTap: (index) => handleTapEvent(index),
currentIndex: _curruntIndex,
items: [
BottomNavigationBarItem(
icon: Icon(
Icons.home,
),
title: Text('Home'),
),
BottomNavigationBarItem(
icon: Icon(
Icons.notifications,
),
title: Text('Notifications'),
),
BottomNavigationBarItem(
icon: Icon(
Icons.lock,
),
title: Text('Profile'),
)
],
),
);
}
}
Consider using IndexedStack like this. It will save the state of the previous widget while moving to another.
body: IndexedStack(.....),
bottomNavigationBar: BottomNavigationBar(
onTap: (index) => handleTapEvent(index),
currentIndex: _curruntIndex,
items: [
BottomNavigationBarItem(
icon: Icon(
Icons.home,
),
title: Text('Home'),
),
BottomNavigationBarItem(
icon: Icon(
Icons.notifications,
),
title: Text('Notifications'),
),
BottomNavigationBarItem(
icon: Icon(
Icons.lock,
),
title: Text('Profile'),
)
],
),
IndexedStack Widget Video
Tutorial on medium

Flutter Drawer Overlaps the bottom Navigation bar

----------
Here is the 1st-screenshot of my problem
This is the 2nd-second screenshot when after implementing single child scrolled view
I have created a navigation drawer and a Bottom navigation widget, i have face the following problems/
While opening drawer it says the drawer exceeds XX pixels so i wrapped it up in "Single child scroll view and now the drawer opens up like a whole page.
Also, when drawer is pressed the Bottom navigation overlaps it.
I have added images which you can see through my clicking above.
here is my piece of code.
class Mydrawer extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
home: Scaffold(
body: SingleChildScrollView(
child: Column(
children: <Widget>[
UserAccountsDrawerHeader(
accountName: Text('Name'),
accountEmail: Text('Username'),
currentAccountPicture: CircleAvatar(
backgroundColor: Colors.white,
child: Text('Hi'),
),
),
ListTile(
leading: Icon(Icons.home),
title: Text(
'Home Page',
),
onTap: () {
Navigator.of(context).pop();
Navigator.of(context).pushNamed(MyHomepage.route);
}),
ListTile(
leading: Icon(Icons.person),
title: Text(
'My Account',
),
onTap: () {
Navigator.of(context).pop();
Navigator.of(context).pushNamed(Account.route);
},
),
ListTile(
leading: Icon(Icons.assignment),
title: Text(
'My Lists',
),
onTap: () {
Navigator.of(context).pop();
Navigator.of(context).pushNamed(Mylist.route);
},
),
ListTile(
leading: Icon(Icons.bookmark),
title: Text(
'Wishlist',
),
onTap: () {
Navigator.of(context).pop();
Navigator.of(context).pushNamed(Wishlist.route);
},
),
Divider(),
ListTile(
leading: Icon(Icons.mail),
title: Text(
'Contact us',
),
onTap: () {
Navigator.of(context).pop();
Navigator.of(context).pushNamed(Contactus.route);
},
),
ListTile(
leading: Icon(Icons.info),
title: Text(
'Info & FAQ',
),
onTap: () {
Navigator.of(context).pop();
Navigator.of(context).pushNamed(Infofaq.route);
},
),
Divider(),
ListTile(
leading: Icon(Icons.lock_open),
title: Text(
'Logout',
),
onTap: () {
Navigator.pop(context);
},
),
],
),
),
),
);
}
}
Bottom Navigation Code
class Nav extends StatefulWidget {
#override
_NavState createState() => _NavState();
}
class _NavState extends State<Nav> {
int _selectedIndex = 0;
final List<Widget> _widgetOptions = [
NavHome(),
NavInspiration(),
NavNotification(),
NavMessages(),
];
void _onitemtap(int index) {
setState(() {
_selectedIndex = index;
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: _widgetOptions[_selectedIndex],
bottomNavigationBar: BottomNavigationBar(
showSelectedLabels: false,
showUnselectedLabels: false,
type: BottomNavigationBarType.fixed,
onTap: _onitemtap,
currentIndex: _selectedIndex,
items: const <BottomNavigationBarItem>[
BottomNavigationBarItem(
icon: Icon(Icons.home),
title: Text('Home'),
),
BottomNavigationBarItem(
icon: Icon(Icons.filter_none),
title: Text('Inspiration'),
),
BottomNavigationBarItem(
icon: Icon(Icons.notifications_none),
title: Text('Notifications'),
),
BottomNavigationBarItem(
icon: Icon(Icons.mail_outline),
title: Text('Messages'),
),
],
),
);
}
}
Main Dart
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Flutter demo',
home: Nav(),
theme: ThemeData(
primarySwatch: Colors.blue,
),
//home: Homepage(),
//initialRoute: '/',
routes: {
MyHomepage.route: (_) => MyHomepage(),
Account.route: (_) => Account(),
Mylist.route: (_) => Mylist(),
Wishlist.route: (_) => Wishlist(),
Contactus.route: (_) => Contactus(),
Infofaq.route: (_) => Infofaq(),
},
);
}
}
----------
Check this!
It's work for me
use drawer part of scaffold().
The best thing that can be done here is, just like you have your Drawer seperate, create a seperate navbar class with no scaffold or body, just the navbar. Now, call both of these, the drawer and the navbar, in a third widget, which contains your scaffold. For changing the index, you can pass the function as a parameter to your navbar widget.
i have changed how u relay your codes, try implementing this in your code. and i have decomposed Nav(), so take in mind that im not using the Nav() as awhole
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
body: MainEntry(),
theme: ThemeData(
primarySwatch: Colors.blue,
),
//home: Homepage(),
//initialRoute: '/',
routes: {
MyHomepage.route: (_) => MyHomepage(),
Account.route: (_) => Account(),
Mylist.route: (_) => Mylist(),
Wishlist.route: (_) => Wishlist(),
Contactus.route: (_) => Contactus(),
Infofaq.route: (_) => Infofaq(),
},
);
}
}
class MainEntry extends StatefulWidget {
#override
_MainEntryState createState() => _MainEntryState();
}
class _MainEntryState extends State<MainEntry> {
#override
Widget build(BuildContext context) {
return MaterialApp(debugShowCheckedBanner: false,
home: Scaffold(
drawer: MyDrawer(),
body: _widgetOptions[_selectedIndex] //your body
bottomNavigationBar: BottomNavigationBar(
showSelectedLabels: false,
showUnselectedLabels: false,
type: BottomNavigationBarType.fixed,
onTap: _onitemtap,
currentIndex: _selectedIndex,
items: const <BottomNavigationBarItem>[
BottomNavigationBarItem(
icon: Icon(Icons.home),
title: Text('Home'),
),
BottomNavigationBarItem(
icon: Icon(Icons.filter_none),
title: Text('Inspiration'),
),
BottomNavigationBarItem(
icon: Icon(Icons.notifications_none),
title: Text('Notifications'),
),
BottomNavigationBarItem(
icon: Icon(Icons.mail_outline),
title: Text('Messages'),
),
],
)
)
);
}
}