Page started at begin when navigate between 2 screen using BottomTabNavigator - flutter

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

Related

Flutter AutoTabsRoute.pageview child not changes (auto_route)

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),
),
],
),
);
},
);

How do I set the bottom navigation bar for a Flutter app page by page?

I would like to set whether to show the bottom navigation bar in a Flutter app page/screen/route by route. For example, when the user navigates through their files and clicks on folders, I want to show the bottom navigation bar. But when the user clicks on a "Create" button, I would not like the bottom navigation for the rest of this flow, and the user navigates backward through the back button in the app bar.
If this is not possible without a very customized, hacky, inflexible, complication solution, I would also be fine with choosing at the beginning of the flow whether to remove the bottom navigation bar.
I have tried the "normal" method, in which the bottom navigation bar only stays for the buttons that are in the bar itself, and it does not persist for anything else (using an IndexedStack and a _currentIndex variable). I have also tried the opposite, in which the bottom navigation shows for everything, which is also not desirable.
Here's what I have currently:
MyApp top-level widget:
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flytrap Audio',
debugShowCheckedModeBanner: false,
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: const CurrentPage(),
);
}
CurrentPageState (stateful) Widget
Widget build(BuildContext context) {
return Scaffold(
body: IndexedStack(
index: _currentIndex,
children: screens,
),
bottomNavigationBar: BottomNavigationBar(
type: BottomNavigationBarType.fixed,
showUnselectedLabels: false,
currentIndex: _currentIndex,
onTap: (index) {
// debugPrint("index: $index");
setState(() => _currentIndex = index);
// _navigatorKey.currentState!
// .pushNamedAndRemoveUntil(screens[index], (route) => false);
// debugPrint("Navigated to ${screens[index]}");
},
items: const <BottomNavigationBarItem>[
BottomNavigationBarItem(
icon: Icon(Icons.folder),
label: 'Files',
),
BottomNavigationBarItem(
icon: Icon(Icons.live_tv),
label: 'Live Broadcasts',
),
BottomNavigationBarItem(
icon: Icon(Icons.settings),
label: 'Settings',
),
],
),
);
}
And each page, like FolderPage is a Scaffold
I think you can check my code, I do the little same as you said.But I use the PageView instead:
final _listPage = [
const Page1(),
const Page2(),
const Page3(),
const Page4()
];
final _controller = PageController();
int _indexSelected = 0;
void _onSelected(int index) {
setState(() {
_indexSelected = index;
});
}
Widget build(BuildContext context) {
return Scaffold(
body: PageView(
controller: _controller,
onPageChanged: _onSelected,
children: _listPage,
),
bottomNavigationBar: BottomNavigationBar(
items: const [
BottomNavigationBarItem(
icon: ImageIcon(
AssetImage('assets/images/bottom_tab/bw_u.png'),
size: 25,
),
label: 'Item 0'),
BottomNavigationBarItem(
icon: Icon(Icons.shopping_bag), label: 'Item 1'),
BottomNavigationBarItem(
icon: Icon(Icons.account_circle_outlined), label: 'Item 2'),
BottomNavigationBarItem(icon: Icon(Icons.widgets), label: 'Item 3')
],
currentIndex: _indexSelected,
onTap: (index) => _controller.animateToPage(index,
duration: const Duration(milliseconds: 200), curve: Curves.easeIn),
selectedItemColor: const Color.fromARGB(255, 38, 112, 205),
unselectedItemColor: Colors.grey,
type: BottomNavigationBarType.fixed,
),
);
}

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)

Flutter BottomNavigationBar: why selected item shifts other icons?

I'm new to flutter and I created a BottomNavigationBar and add into it some BottomNavigationBarItem that contains flutter icons.
The problem is that, when I select one item of my BottomNavigationBar, this item shifts other icons.
this is a screenshot of my app:
is there a way to block this shift ?
my code:
import 'package:flutter/material.dart';
class Navbar extends StatefulWidget {
const Navbar({ Key key }) : super(key: key);
#override
_NavbarState createState() => _NavbarState();
}
class _NavbarState extends State<Navbar> {
int index = 0;
#override
Widget build(BuildContext context) {
return BottomNavigationBar(
iconSize: 30,
showSelectedLabels: false,
showUnselectedLabels: false,
selectedItemColor: Colors.blueGrey,
unselectedItemColor: Colors.black,
currentIndex: index,
onTap: (int selectedIndex) {
setState(() {
index = selectedIndex;
});
},
items: [
BottomNavigationBarItem(
icon: new Icon(
Icons.home,
),
title: new Text('Home'),
),
BottomNavigationBarItem(
icon: new Icon(
Icons.search,
),
title: new Text('Search'),
),
BottomNavigationBarItem(
icon: Icon(
Icons.add,
),
title: Text('Add')
),
BottomNavigationBarItem(
icon: Icon(
Icons.favorite,
),
title: Text('Add')
),
BottomNavigationBarItem(
icon: Icon(
Icons.account_circle,
),
title: Text('Account')
)
],
);
}
}
You can change this behavior of the BottomNavigationBar by setting its type parameter to BottomNavigationBarType.fixed when constructing it.
BottomNavigationBar(
...
type: BottomNavigationBarType.fixed,
...
}
According to the documentation the default type is fixed if there are four or less items and shifting if there are more.

Set color on active item in a BottomNavigationBarType.fixed

I have a fixed BottomNavigationBar with 4 items as described below.
How can I set the color of the selected item?
I've tried with: fixedColor and selectedItemColor but it would't work.
BottomNavigationBar(
type: BottomNavigationBarType.fixed,
fixedColor: Colors.blue,
//selectedItemColor: Colors.blue,
currentIndex: snapshot.data.index,
onTap: _bottomNavBarBloc.pickItem,
items: [
BottomNavigationBarItem(
icon: Icon(
Icons.access_time,
color: Colors.black,
),
),
BottomNavigationBarItem(...),
BottomNavigationBarItem(...),
BottomNavigationBarItem(...),
]);
You can provide a different icon for Active and Normal Bottom Navigation Item.
BottomNavigationBarItem _getNavigationItem(IconData icon, String title) {
return BottomNavigationBarItem(
backgroundColor: Colors.white,
activeIcon: Icon(
icon,
color: Colors.teal,
),
icon: Icon(icon, color: Colors.grey),
title: Text(title),
);
}
There are two types available. fixed or shifting. If we add fixed type , the buttons inside bottom navigation does not show any effect when use click a particular button. It just keep fixed to the bottom navigation. If we add shifting , it will show some kind of cool animation when we click a particular button.
Check this out here
A workaround perhaps would be something like this though:
import 'package:flutter/material.dart';
void main() {
runApp(new MaterialApp(
home: new MyHomePage(),
));
}
class MyHomePage extends StatefulWidget {
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
int currentIndex = 0;
Widget build(BuildContext context) {
return new Scaffold(
appBar: AppBar(
title: Text("StackoverFlow"),
),
body: Container(),
bottomNavigationBar: BottomNavigationBar(
type: BottomNavigationBarType.fixed,
currentIndex: currentIndex,
onTap: (index) {
setState(() {
currentIndex = index;
});
},
items: [
BottomNavigationBarItem(
icon: Icon(
Icons.access_time,
color: currentIndex == 0? Colors.blue:Colors.black,
),
title: Container(),
),
BottomNavigationBarItem(
icon: Icon(
Icons.access_time,
color: currentIndex == 1? Colors.blue:Colors.black,
),
title: Container(),
),
]),
);
}
}