Flutter - How to change index of BottomNavigationBar if NavigationBar is not visible? - flutter

This is my setup:
Home.dart
final List<Widget> _pages = [
Screen1(),
Screen2(),
Screen3(),
Screen4(),
];
int _selectedPageIndex = 0;
void _selectPage(int index) {
setState(() {
_selectedPageIndex = index;
});}
#override
Widget build(BuildContext context) {
return Scaffold(
extendBodyBehindAppBar: true,
body: _pages[_selectedPageIndex],
bottomNavigationBar: _selectedPageIndex != 2
? Column(mainAxisSize: MainAxisSize.min, children: <Widget>[
...
Now when we navigate to Screen3() I'm hiding the complete BottomNavigationBar and show the Screen in Fullscreen. With a button I want to navigate back to any other position. How to do this? I don't want to use any Routes to close. How can we access _selectedPageIndex or do you have another good idea?
Would appreciate any ideas.

You can copy paste run full code below
Step 1: keep previous index, needed when go back from full screen page
void _onItemTapped(int index) {
setState(() {
_previousIndex = _selectedPageIndex;
_selectedPageIndex = index;
});
}
Step 2: pass refresh() callback to full screen page here is Setting()
void refresh() {
setState(() {
_selectedPageIndex = _previousIndex;
});
}
...
case 2:
{
print("settings");
return Settings(
callback: refresh,
);
}
Step 3: In full screen page's Raised Button call this callback
RaisedButton(
onPressed: () {
widget.callback();
},
child: Text("Go back"),
)
working demo
full code
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
/// This Widget is the main application widget.
class MyApp extends StatelessWidget {
static const String _title = 'Flutter Code Sample';
#override
Widget build(BuildContext context) {
return MaterialApp(
title: _title,
home: MyStatefulWidget(),
);
}
}
class MyStatefulWidget extends StatefulWidget {
MyStatefulWidget({Key key}) : super(key: key);
#override
_MyStatefulWidgetState createState() => _MyStatefulWidgetState();
}
class _MyStatefulWidgetState extends State<MyStatefulWidget> {
int _selectedPageIndex = 0;
int _previousIndex = 0;
void refresh() {
setState(() {
_selectedPageIndex = _previousIndex;
});
}
void _onItemTapped(int index) {
setState(() {
_previousIndex = _selectedPageIndex;
_selectedPageIndex = index;
});
}
Widget pageCaller(int index) {
print(index);
switch (index) {
case 0:
{
return Category();
}
case 1:
{
return Feed();
}
case 2:
{
print("settings");
return Settings(
callback: refresh,
);
}
}
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Home'),
),
body: Center(
child: pageCaller(_selectedPageIndex),
),
bottomNavigationBar: _selectedPageIndex == 2
? null
: BottomNavigationBar(
items: const <BottomNavigationBarItem>[
BottomNavigationBarItem(
icon: Icon(Icons.home),
title: Text('Category'),
),
BottomNavigationBarItem(
icon: Icon(Icons.business),
title: Text('Feed'),
),
BottomNavigationBarItem(
icon: Icon(Icons.school),
title: Text('Settings'),
),
],
currentIndex: _selectedPageIndex,
selectedItemColor: Colors.amber[800],
onTap: _onItemTapped,
),
);
}
}
class Category extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Text("Category"),
),
);
}
}
class Feed extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Text("Feed"),
),
);
}
}
class Settings extends StatefulWidget {
VoidCallback callback;
Settings({this.callback});
#override
_SettingsState createState() => _SettingsState();
}
class _SettingsState extends State<Settings> {
#override
Widget build(BuildContext context) {
return Scaffold(
body: Column(
children: [
Text("This is setting page"),
RaisedButton(
onPressed: () {
widget.callback();
},
child: Text("Go back"),
),
],
));
}
}

Related

Why doesn't BottomNavigatorBarItem currentIndex get updated?

I am new to flutter and I did find similar questions on SO but am too novice to understand the nuance so apologies if this question is too similar to an already asked one.
I have a BottomNavigationBar which has 3 icons (Home, Play and Create) which should navigate between these 3 routes/pages.
main.dart
routes: {
"/home": (context) => MyHomePage(title: "STFU"),
"/play": (context) => Play(),
"/create": (context) => Create(),
"/settings": (context) => Settings(),
},
I extracted my navbar into a custom class so my 3 separate pages could use it:
bottom-nav.dart
class MyBottomNavBar extends StatefulWidget {
MyBottomNavBar({
Key? key,
}) : super(key: key);
#override
State<MyBottomNavBar> createState() => _MyBottomNavBarState();
}
class _MyBottomNavBarState extends State<MyBottomNavBar> {
int _selectedIndex = 0;
void _onTapped(int index) => {
print("_onTapped called with index = $index"),
setState(
() => _selectedIndex = index,
)
};
#override
Widget build(BuildContext context) {
return BottomNavigationBar(
backgroundColor: Colors.orangeAccent[100],
currentIndex: _selectedIndex,
onTap: (value) => {
print("value is $value"),
// find index and push that
_onTapped(value),
if (value == 0)
{Navigator.pushNamed(context, "/home")}
else if (value == 1)
{Navigator.pushNamed(context, "/play")}
else if (value == 2)
{Navigator.pushNamed(context, "/create")}
},
items: [
BottomNavigationBarItem(label: "Home", icon: Icon(Icons.home_filled)),
BottomNavigationBarItem(
label: "Play", icon: Icon(Icons.play_arrow_rounded)),
BottomNavigationBarItem(label: "Create", icon: Icon(Icons.create)),
],
);
}
}
so now i just set this MyBottomNavBar class to the bottomNavigationBar property of the Scaffold widget my inside Home page, Play page and Create page for eg.
home.dart
class _MyHomePageState extends State<MyHomePage> {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Home"),
),
body: Column(
children: [
Container(
padding: EdgeInsets.all(20.00),
child: Text("inside home"),
),
],
),
bottomNavigationBar: MyBottomNavBar(),
);
}
}
play.dart
class Play extends StatefulWidget {
const Play({super.key});
#override
State<Play> createState() => _PlayState();
}
class _PlayState extends State<Play> {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(),
body: Container(
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Text("inside play page"),
SizedBox(
height: 30.00,
),
Text("some text"),
],
),
),
bottomNavigationBar: MyBottomNavBar(),
);
}
}
The nav bar buttons work to switch between pages but for some reason the currentIndex value isn't getting updated and stays at 0 (i.e on the "Home" icon). When I debug it I can see _selectedIndex getting updated inside inside the _onTapped function which should update the currentIndex value but it doesn't appear to do so. Any help would be appreciated
What you have here is three different pages with their separate BottomNavBar class instance. Instead you should have a shared Scaffold and one bottomNavBar so that when you navigate bottomNavbar state does not reset.
You can use PageView to do this.
class MyHomePage extends StatefulWidget {
const MyHomePage({super.key});
#override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
#override
void initState() {
super.initState();
}
List<Widget> pages = const [Home(), Play(), Create()];
final _pageController = PageController();
int _selectedIndex = 0;
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(),
bottomNavigationBar: BottomNavigationBar(
currentIndex: _selectedIndex,
onTap: (index) {
_pageController.jumpToPage(index);
_selectedIndex = index;
setState(() {});
},
items: const [
BottomNavigationBarItem(icon: Icon(Icons.home), label: 'Home'),
BottomNavigationBarItem(icon: Icon(Icons.play_arrow), label: 'Play'),
BottomNavigationBarItem(icon: Icon(Icons.create), label: 'Create'),
],
backgroundColor: Colors.greenAccent,
),
body: PageView(
controller: _pageController,
children: pages,
),
);
}
}
class Home extends StatelessWidget {
const Home({super.key});
#override
Widget build(BuildContext context) {
return const Placeholder();
}
}
class Play extends StatelessWidget {
const Play({super.key});
#override
Widget build(BuildContext context) {
return const Placeholder();
}
}
class Create extends StatelessWidget {
const Create({super.key});
#override
Widget build(BuildContext context) {
return const Placeholder();
}
}

Preserve state of widget in flutter even though parent widget rebuilds

I'm trying to preserve the state of widget pages when switching between widgets using BottomNavigationBar. I've read here that I can do this using IndexedStack, however, that doesn't work in my case for two reasons:
The Scaffold in which the pages are displayed gets rebuilt when switching between pages because for some, but not all, pages the Scaffold should be extended: Scaffold( extendBody: _pageIndex == 1, ...)
The pages should be built for the first time just when the page is opened for the first time and not right from the start
Here's a small example that shows that IndexStack is not working as intended because the Scaffold rebuilds:
class Home extends StatefulWidget {
#override
_HomeState createState() => _HomeState();
}
class _HomeState extends State<Home> {
int _pageIndex = 1;
List<Widget> _pages = [Text("hi"), Counter()];
#override
Widget build(BuildContext context) {
return Scaffold(
extendBody: _pageIndex == 1,
appBar: AppBar(),
body: IndexedStack(
children: _pages,
index: _pageIndex,
),
bottomNavigationBar: BottomNavigationBar(
items: [
BottomNavigationBarItem(icon: Icon(Icons.home), label: 'Goto 0',),
BottomNavigationBarItem(icon: Icon(Icons.business), label: 'Goto 1',),
],
currentIndex: _pageIndex,
onTap: (int index) {
setState(() {
_pageIndex = index;
});
print("idx " + _pageIndex.toString());
},
),
);
}
}
Demo showing that the state is not preserved
This is the Counter which can be replaced by any other stateful widget:
class Counter extends StatefulWidget {
#override
_CounterState createState() => _CounterState();
}
//this part is not important, just to show that state is lost
class _CounterState extends State<Counter> {
int _count = 0;
#override
void initState() {
_count = 0;
super.initState();
}
#override
Widget build(BuildContext context) {
return Center(
child: TextButton(
child: Text("Count: " + _count.toString(), style: TextStyle(fontSize: 20),),
onPressed: () {
setState(() {
_count++;
});
},
),
);
}
}
First off, great question! The trick is to use KeyedSubtree, and conditionally render pages depending on if they have been visited yet or not.
You could adapt your code this way to achieve your desired behavior:
class Page {
const Page(this.subtreeKey, {required this.child});
final GlobalKey subtreeKey;
final Widget child;
}
class Home extends StatefulWidget {
#override
_HomeState createState() => _HomeState();
}
class _HomeState extends State<Home> {
var _pageIndex = 1;
final _pages = [
Page(GlobalKey(), child: Text('Hi')),
Page(GlobalKey(), child: Counter()),
];
final _builtPages = List<bool>.generate(2, (_) => false);
#override
Widget build(BuildContext context) {
return Scaffold(
extendBody: _pageIndex == 1,
appBar: AppBar(),
body: Stack(
fit: StackFit.expand,
children: _pages.map(
(page) {
return _buildPage(
_pages.indexOf(page),
page,
);
},
).toList(),
),
bottomNavigationBar: BottomNavigationBar(
items: [
BottomNavigationBarItem(
icon: Icon(Icons.home),
label: 'Goto 0',
),
BottomNavigationBarItem(
icon: Icon(Icons.business),
label: 'Goto 1',
),
],
currentIndex: _pageIndex,
onTap: (int index) {
setState(() {
_pageIndex = index;
});
print("idx " + _pageIndex.toString());
},
),
);
}
Widget _buildPage(
int tabIndex,
Page page,
) {
final isCurrentlySelected = tabIndex == _pageIndex;
_builtPages[tabIndex] = isCurrentlySelected || _builtPages[tabIndex];
final Widget view = KeyedSubtree(
key: page.subtreeKey,
child: _builtPages[tabIndex] ? page.child : Container(),
);
if (tabIndex == _pageIndex) {
return view;
} else {
return Offstage(child: view);
}
}
}
You should be able to modify this code to add more tabs, functionality, etc.

How do I make BottomNavigationBar page transition with Flutter's onWillpop?

I am using BottomNavigationBar in Flutter Project.
This question is for line 30 "//TODO: back to the FirstTab".
When a user is in the SecondTab or ThirdTab and the BackButton in the Android device is pressed, I want the user to go to the FirstTab.
Now, in onWillpopScope, there is a process to pop when you can. It is used when the user is in NextPage.
Then, when the user is not in the FirstTab (SecondTab or ThirdTab) and not in the NextTab, I want to move him to the FirstTab in onWillpopScope. (I want to force the BottomNavigationBar to switch.)
How should I describe it? Please tell me.
import 'package:flutter/material.dart';
import 'package:flutter/cupertino.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatefulWidget {
#override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
List<GlobalKey<NavigatorState>> navigatorKeys = [
GlobalKey<NavigatorState>(),
GlobalKey<NavigatorState>(),
GlobalKey<NavigatorState>(),
];
#override
Widget build(BuildContext context) {
int currentIndex = 0;
return MaterialApp(
home: WillPopScope(
onWillPop: () async {
final isFirstRouteInCurrentTab = await navigatorKeys[currentIndex].currentState.maybePop();
if (isFirstRouteInCurrentTab) {
if (currentIndex != 0) {
//TODO: back to the FirstTab
return false;
}
}
return isFirstRouteInCurrentTab;
},
child: CupertinoTabScaffold(
tabBar: CupertinoTabBar(
items: <BottomNavigationBarItem>[
BottomNavigationBarItem(label: 'Home', icon: Icon(Icons.home)),
BottomNavigationBarItem(label: 'Search', icon: Icon(Icons.search)),
BottomNavigationBarItem(label: 'Setting', icon: Icon(Icons.settings)),
],
onTap: (index) {
// back home only if not switching tab
if (currentIndex == index) {
switch (index) {
case 0:
navigatorKeys[index].currentState.popUntil((route) => route.isFirst);
break;
case 1:
navigatorKeys[index].currentState.popUntil((route) => route.isFirst);
break;
case 2:
navigatorKeys[index].currentState.popUntil((route) => route.isFirst);
break;
}
}
currentIndex = index;
},
currentIndex: currentIndex,
),
tabBuilder: (BuildContext context, int index) {
return CupertinoTabView(
navigatorKey: navigatorKeys[index],
builder: (BuildContext context) {
switch (index) {
case 0:
return FirstTab();
case 1:
return SecondTab();
case 2:
return ThirdTab();
default:
return FirstTab();
}
},
);
},
),
),
);
}
}
class FirstTab extends StatelessWidget {
#override
Widget build(BuildContext context) {
return CupertinoPageScaffold(
navigationBar: CupertinoNavigationBar(
middle: Text('first page now'),
),
backgroundColor: Colors.red[200],
child: Center(
child: CupertinoButton(
child: const Text('Next'),
onPressed: () {
Navigator.of(context).push(CupertinoPageRoute(builder: (context) => NextPage()));
},
),
),
);
}
}
//Different color from Firsttab
class SecondTab extends StatelessWidget {}
//Different color from Firsttab
class ThirdTab extends StatelessWidget {}
class NextPage extends StatelessWidget {
#override
Widget build(BuildContext context) {
return CupertinoPageScaffold(
navigationBar: CupertinoNavigationBar(
middle: Text('second page now'),
),
backgroundColor: Colors.white,
child: Center(
child: CupertinoButton(
child: const Text('Back'),
onPressed: () {
Navigator.of(context).pop();
},
),
),
);
}
}
You can try to see it docs.
I'll resume here. First you need to create a controller
final CupertinoTabController _controller = CupertinoTabController();
and add to your CupertinoTabScaffold like this
CupertinoTabScaffold(
...
controller: _controller,
)
in the end you change the page like this:
_controller.index = 0,
(this is how get and set work in Flutter)
first move
int currentIndex = 0;
to class member
next
//TODO: back to the FirstTab
setState((){
currentIndex = 0;
});

Is it possible for me to choose to show or hide bottom navigation bar when I move to new page with navigator in flutter?

everyone.
I'm making an app which has bottom navigation bar with two items, and each item has buttons to move new pages.
Let's say each of those item is called for A and B.
A has a button for moving to new Page C. C shows today's weather. And I want to see bottom navigation bar in C as well.
B also has a button for moving to new Page D. D is login page. And I don't want to see bottom navigation bar in D.
I tried to use IndexedStack and GlobalKey, and it did work for showing bottom navigation bar in C. But I failed to hide bottom navigation bar with it in D.
I also read many articles here and there but never worked.
Can anybody help me?
class HomePage extends StatefulWidget {
#override
_HomePageState createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
int _currentTab;
List<Widget> _tabList = [
FirstTab(),
SecondTab()
];
#override
void initState() {
super.initState();
_currentTab = 0;
}
void onItemTapped(int index) {
setState(() {
_currentTab = index;
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: _tabList[_currentTab],
bottomNavigationBar: BottomNavigationBar(
items: const <BottomNavigationBarItem>[
BottomNavigationBarItem(
icon: Icon(Icons.calendar_today),
title: Text('Weather')
),
BottomNavigationBarItem(
icon: Icon(Icons.person),
title: Text('Login')
)
],
onTap: onItemTapped,
currentIndex: _currentTab,
),
);
}
}
class FirstTab extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: RaisedButton(
onPressed: () {
Navigator.push(context, MaterialPageRoute(builder: (context) => WeatherPage()));
},
child: Text('To see the weather today'),
),
),
);
}
}
class SecondTab extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: RaisedButton(
onPressed: () {
Navigator.push(context, MaterialPageRoute(builder: (context) => LoginPage()));
},
child: Text('To Login'),
),
),
);
}
}
class WeatherPage extends StatelessWidget { // This page needs bottom navigation bar
#override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Text('Rainy'),
),
);
}
}
class LoginPage extends StatelessWidget { // There is no bottom navigation bar on this page
#override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Text('Click to login'),
),
);
}
}
Edit:
Have a new bottomNavbar in the WeatherPage (first solution in comment section):
import 'package:flutter/material.dart';
class StackOverflow2 extends StatefulWidget {
#override
_StackOverflow2State createState() => _StackOverflow2State();
}
class _StackOverflow2State extends State<StackOverflow2> {
int _currentTab;
List<Widget> _tabList = [FirstTab(), SecondTab()];
#override
void initState() {
super.initState();
_currentTab = 0;
}
void onItemTapped(int index) {
setState(() {
_currentTab = index;
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: _tabList[_currentTab],
bottomNavigationBar: BottomNavigationBar(
items: const <BottomNavigationBarItem>[
BottomNavigationBarItem(
icon: Icon(Icons.calendar_today), title: Text('Weather')),
BottomNavigationBarItem(
icon: Icon(Icons.person), title: Text('Login'))
],
onTap: onItemTapped,
currentIndex: _currentTab,
),
);
}
}
class WeatherPage extends StatefulWidget {
// Th
#override
_WeatherPageState createState() => _WeatherPageState();
}
class _WeatherPageState extends State<WeatherPage> {
int _currentTab;
Widget myCenter = Center(
child: Text('Rainy'),
);
List<Widget> _tabList;
#override
void initState() {
super.initState();
_tabList = [myCenter, SecondTab()];
_currentTab = 0;
}
void onItemTapped(int index) {
setState(() {
_currentTab = index;
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: _tabList[_currentTab],
bottomNavigationBar: BottomNavigationBar(
items: const <BottomNavigationBarItem>[
BottomNavigationBarItem(
icon: Icon(Icons.calendar_today), title: Text('Weather')),
BottomNavigationBarItem(
icon: Icon(Icons.person), title: Text('Login'))
],
onTap: onItemTapped,
currentIndex: _currentTab,
),
);
}
}
class FirstTab extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: RaisedButton(
onPressed: () {
Navigator.push(context,
MaterialPageRoute(builder: (context) => WeatherPage()));
},
child: Text('To see the weather today'),
),
),
);
}
}
class SecondTab extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: RaisedButton(
onPressed: () {
Navigator.push(
context, MaterialPageRoute(builder: (context) => LoginPage()));
},
child: Text('To Login'),
),
),
);
}
}
class LoginPage extends StatelessWidget {
// There is no bottom navigation bar on this page
#override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Text('Click to login'),
),
);
}
}

How to jump to another page with pageview flutter

Hello I tried to jump to my second page tab if I press on a button on my first Page tab. Currently I know only call route of my seconde page widget but bottomnavbar isn't present... I don't know how to call my parent widget from my first page tab to jump to the seconde page tab.
class Parent {
int bottomSelectedIndex = 0;
List<BottomNavigationBarItem> buildBottomNavBarItems() {
return [
BottomNavigationBarItem(
icon: new Icon(Icons.home),
title: new Text('First')
),
BottomNavigationBarItem(
icon: new Icon(Icons.search),
title: new Text('Second'),
),
];
}
PageController pageController = PageController(
initialPage: 0,
keepPage: true,
);
Widget buildPageView() {
return PageView(
controller: pageController,
onPageChanged: (index) {
pageChanged(index);
},
children: <Widget>[
First(),
Second(),
],
);
}
#override
void initState() {
super.initState();
}
void pageChanged(int index) {
setState(() {
bottomSelectedIndex = index;
});
}
void bottomTapped(int index) {
setState(() {
bottomSelectedIndex = index;
pageController.animateToPage(index, duration: Duration(milliseconds: 500), curve: Curves.ease);
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: buildPageView(),
bottomNavigationBar: BottomNavigationBar(
currentIndex: bottomSelectedIndex,
onTap: (index) {
bottomTapped(index);
},
items: buildBottomNavBarItems(),
),
);
}
}
class first {
return Container(
// here a pressbutton for jump to the second widget
);
}
----------------------------------------------------------
class second
return Container(
);
}
You can use this:
void onAddButtonTapped(int index) {
// use this to animate to the page
pageController.animateToPage(index);
// or this to jump to it without animating
pageController.jumpToPage(index);
}
Pass the function as params:
class first {
final void Function(int) onAddButtonTapped;
return Container(
// call it here onAddButtonTapped(2);
);
}
class Second {
final void Function(int) onAddButtonTapped;
return Container(
);
}
children: <Widget>[
First(onAddButtonTapped),
Second(onAddButtonTapped),
],
You can pass a callback to your first widget and call that when the button is pressed, so you can change the page in the parent widget.
Something like this:
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Test',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: Parent(),
);
}
}
class Parent extends StatefulWidget {
#override
_ParentState createState() => _ParentState();
}
class _ParentState extends State<Parent> {
int bottomSelectedIndex = 0;
List<BottomNavigationBarItem> buildBottomNavBarItems() {
return [
BottomNavigationBarItem(
icon: new Icon(Icons.home), title: new Text('First')),
BottomNavigationBarItem(
icon: new Icon(Icons.search),
title: new Text('Second'),
),
];
}
PageController pageController = PageController(
initialPage: 0,
keepPage: true,
);
Widget buildPageView() {
return PageView(
controller: pageController,
onPageChanged: (index) {
pageChanged(index);
},
children: <Widget>[
FirstWidget(
onButtonPressed: () => pageController.animateToPage(
1,
duration: Duration(milliseconds: 300),
curve: Curves.linear,
),
),
SecondWidget(),
],
);
}
#override
void initState() {
super.initState();
}
void pageChanged(int index) {
setState(() {
bottomSelectedIndex = index;
});
}
void bottomTapped(int index) {
setState(() {
bottomSelectedIndex = index;
pageController.animateToPage(index,
duration: Duration(milliseconds: 500), curve: Curves.ease);
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Test'),
),
body: buildPageView(),
bottomNavigationBar: BottomNavigationBar(
currentIndex: bottomSelectedIndex,
onTap: (index) {
bottomTapped(index);
},
items: buildBottomNavBarItems(),
),
);
}
}
class FirstWidget extends StatefulWidget {
final VoidCallback onButtonPressed;
FirstWidget({#required this.onButtonPressed});
#override
_FirstWidgetState createState() => _FirstWidgetState();
}
class _FirstWidgetState extends State<FirstWidget> {
#override
Widget build(BuildContext context) {
return Container(
color: Colors.red,
child: Center(
child: FlatButton(
onPressed: widget.onButtonPressed,
child: Text('Go to second page'),
),
),
);
}
}
class SecondWidget extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Container(color: Colors.green);
}
}