Flutter pop to root when bottom navigation tapped - flutter

I want implement feature that when user taps BottomNavigationBarItem pop to root if current page index equal to tapped index like normal iOS app.
I tried like below. I set all root pages route in MaterialApp and in HomeScreen if currentIndex equal to index, popUntil to root page.
However error says
flutter: The following StateError was thrown while handling a gesture:
flutter: Bad state: Future already completed
How could I make this work?
Code:
// MyApp class
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return new MaterialApp(
routes: <String, WidgetBuilder>{
'/Page1': (BuildContext context) => new Page1(),
'/Page2': (BuildContext context) => new Page2(),
'/Page3': (BuildContext context) => new Page3(),
'/Page4': (BuildContext context) => new Page4(),
},
title: 'Flutter Example',
home: new HomeScreen(),
);
}
}
// MyHome class
class HomeScreen extends StatefulWidget {
#override
_HomeScreenState createState() => new _HomeScreenState();
}
class _HomeScreenState extends State<HomeScreen> {
final List<StatelessWidget> pages = [
new Page1(),
new Page2(),
new Page3(),
new Page3(),
];
final List<String> routes = [
'/Page1',
'/Page2',
'/Page3',
'/Page4',
];
int currentIndex = 0;
#override
Widget build(BuildContext context) {
return new WillPopScope(
onWillPop: () => new Future<bool>.value(true),
child: new CupertinoTabScaffold(
tabBar: new CupertinoTabBar(
onTap: (index) {
if (index == currentIndex) {
Navigator.popUntil(context, ModalRoute.withName(routes[index]));
}
currentIndex = index;
},
backgroundColor: Colors.white,
activeColor: Colors.blue,
inactiveColor: Colors.grey,
items: const <BottomNavigationBarItem>[
BottomNavigationBarItem(
icon: Icon(Icons.looks_one),
title: Text('Page1'),
),
BottomNavigationBarItem(
icon: Icon(Icons.looks_two),
title: Text('Page2'),
),
BottomNavigationBarItem(
icon: Icon(Icons.looks_3),
title: Text('Page3'),
),
BottomNavigationBarItem(
icon: Icon(Icons.looks_4),
title: Text('Page4'),
),
],
),
tabBuilder: (BuildContext context, int index) {
return new DefaultTextStyle(
style: const TextStyle(
fontFamily: '.SF UI Text',
fontSize: 17.0,
color: CupertinoColors.black,
),
child: new CupertinoTabView(
builder: (BuildContext context) {
return pages[index];
},
),
);
},
),
);
}
}

It's now possible to achieve this behavior since Flutter v1.1.1 that added navigatorKey to CupertinoTabView
(https://github.com/flutter/flutter/commit/65df90d8b5e1145e1022c365bb0465aa8c30dcdf)
First, you have to declare one GlobalKey<NavigatorState> per tab and then pass it to the corresponding CupertinoTabView constructors.
Then, in the onTap method of your CupertinoTabBar, you can and pop to root with firstTabNavKey.currentState.popUntil((r) => r.isFirst) if the user is tapping while staying in the same tab.
Full example below :
void main() {
runApp(MyApp());
}
class MyApp extends StatefulWidget {
#override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
int currentIndex = 0;
final GlobalKey<NavigatorState> firstTabNavKey = GlobalKey<NavigatorState>();
final GlobalKey<NavigatorState> secondTabNavKey = GlobalKey<NavigatorState>();
final GlobalKey<NavigatorState> thirdTabNavKey = GlobalKey<NavigatorState>();
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'My App',
home: CupertinoTabScaffold(
tabBuilder: (BuildContext context, int index) {
switch (index) {
case 0:
return CupertinoTabView(
navigatorKey: firstTabNavKey,
builder: (BuildContext context) => FirstTab(),
);
break;
case 1:
return CupertinoTabView(
navigatorKey: secondTabNavKey,
builder: (BuildContext context) => SecondTab(),
);
break;
case 2:
return CupertinoTabView(
navigatorKey: thirdTabNavKey,
builder: (BuildContext context) => ThirdTab(),
);
break;
}
return null;
},
tabBar: CupertinoTabBar(
items: <BottomNavigationBarItem> [
BottomNavigationBarItem(
title: Text('Tab 1'),
),
BottomNavigationBarItem(
title: Text('Tab 2'),
),
BottomNavigationBarItem(
title: Text('Tab 3'),
),
],
onTap: (index){
// back home only if not switching tab
if(currentIndex == index) {
switch (index) {
case 0:
firstTabNavKey.currentState.popUntil((r) => r.isFirst);
break;
case 1:
secondTabNavKey.currentState.popUntil((r) => r.isFirst);
break;
case 2:
thirdTabNavKey.currentState.popUntil((r) => r.isFirst);
break;
}
}
currentIndex = index;
},
),
),
);
}
}

you can achieve the same effect with pushAndRemoveUntil (if i'm understanding your need correctly).
final PageRouteBuilder _homeRoute = new PageRouteBuilder(
pageBuilder: (BuildContext context, _, __) {
return HomeScreen();
},
);
void _goHome() {
Navigator.pushAndRemoveUntil(context, _homeRoute, (Route<dynamic> r) => false);
}
this has the added benefit of being able to utilize PageRouteBuilder's other properties.

This simple code worked for me to go to the root
onPressed: () {
Navigator.of(context).pushNamedAndRemoveUntil('/', ModalRoute.withName('/'));
}

The following worked, where in my set up all routes are named:
Navigator.of(context)
.pushNamedAndRemoveUntil('homeScreen', (route) => false);
Thanks to answers from #blaneyneil and #Juanma Menendez

Related

How to fix BottomNavigationBar disappearance issue in Flutter App

I am facing an issue with my bottom navigation bar. The problem is that the bottom navigation bar disappears whenever I navigate to another page.
I am using the following code to navigate to another page:
Navigator.of(context).pushReplacement(MaterialPageRoute(
builder: (BuildContext context) => WorkoutsPage()
));
Here is a summarized part of the BottomBar
class BottomBar extends StatefulWidget {
const BottomBar({Key? key}) : super(key: key);
#override
State<BottomBar> createState() => _BottomBarState();
}
class _BottomBarState extends State<BottomBar> {
int _selectedIndex = 0;
static final List<Widget> _widgetOptions = <Widget>[
HomeScreen(),
WorkoutsPage(),
................
];
void _onItemTapped(int index) {
setState(() {
_selectedIndex = index;
//print('Tapped index is: ${_selectedIndex}');
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: _widgetOptions[_selectedIndex],
),
bottomNavigationBar: Column(
children: [
BottomNavigationBar(
currentIndex: _selectedIndex,
onTap: _onItemTapped,
..................................
type: BottomNavigationBarType.fixed,
items: const [
BottomNavigationBarItem(
icon: Icon(FluentSystemIcons.ic_fluent_home_regular),
activeIcon: Icon(FluentSystemIcons.ic_fluent_home_filled),
label: "Home"),
BottomNavigationBarItem(
icon:
Icon(FluentSystemIcons.ic_fluent_clipboard_text_regular),
activeIcon:
Icon(FluentSystemIcons.ic_fluent_clipboard_text_filled),
label: "Plan"),
Here is the main.dart
#override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
routes: {
'/': (context) => _defaultHome,
'/home': (context) => const BottomBar(),
'/login': (context) => const LoginPage(),
'/register': (context) => const RegisterPage(),
},
);
}
My question what should I do to keep the bottombar when I use
Navigator.of(context).pushReplacement(MaterialPageRoute(
builder: (BuildContext context) => WorkoutsPage()
));
after clicking a submit button or something
BottomBar is a page. When you use pushReplacement, You move to another Scaffold page that is no BottomBar.
An alternative is to turn Column widget of bottomNavigationBar into a separate StatefulWidget and start passing it in all Scaffold pages.
Keep selectedIndex as a global variable so that its value remains even when you change to another route.

Flutter Navigation doesn't pop Navigator stack on back press

I'm using Navigator for named routes to switch pages on screen with a BottomNavigationBar. On Page 3, I can navigate to Page 4 by NavigationKey.currentState.pushNamed(Page4Route).
On Page 4, I'm able to navigate back to Page 3 by calling NavigationKey.currentState.pop, but pressing the back button of the device closes the app instead. Any idea why the back button doesn't pop the current screen on the Navigation stack? How can I handle this better?
Widget build(BuildContext context) {
return Scaffold(
body: Navigator(
key: navigationKey,
initialRoute: Pages.home,
onGenerateRoute: (RouteSettings settings) {
WidgetBuilder builder;
// Manage your route names here
switch (settings.name) {
case Pages.home:
builder = (BuildContext context) => _page1();
break;
case Pages.page1:
builder = (BuildContext context) => _page1();
break;
case Pages.page2:
builder = (BuildContext context) => _page2();
break;
case Pages.page3:
builder = (BuildContext context) => _page3();
break;
case Pages.page4:
builder = (BuildContext context) => Page4Screen(navigatorKey: navigationKey);
break;
default:
throw Exception('Invalid route: ${settings.name}');
}
return MaterialPageRoute(
builder: builder,
settings: settings,
);
},
),
bottomNavigationBar: BottomNavigationBar(),
...
);
}
Demo
Minimal Repro
import 'package:flutter/material.dart';
void main() => runApp(App());
class App extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Nested Routing Demo',
home: HomePage(),
);
}
}
class Pages{
static const home = '/';
static const page1 = '/page1';
static const page2 = '/page2';
static const page3 = '/page3';
static const page4 = '/page4';
}
class HomePage extends StatefulWidget {
#override
_HomeState createState() => _HomeState();
}
class _HomeState extends State<HomePage> {
final GlobalKey<NavigatorState> navigationKey = GlobalKey<NavigatorState>();
var _currentPage = 0;
#override
Widget build(BuildContext context) {
return Scaffold(
body: Navigator(
key: navigationKey,
initialRoute: '/',
onGenerateRoute: (RouteSettings settings) {
WidgetBuilder builder;
// Manage your route names here
switch (settings.name) {
case Pages.home:
builder = (BuildContext context) => _page1();
break;
case Pages.page1:
builder = (BuildContext context) => _page1();
break;
case Pages.page2:
builder = (BuildContext context) => _page2();
break;
case Pages.page3:
builder = (BuildContext context) => _page3();
break;
case Pages.page4:
builder = (BuildContext context) => Page4Screen(navigatorKey: navigationKey);
break;
default:
throw Exception('Invalid route: ${settings.name}');
}
// You can also return a PageRouteBuilder and
// define custom transitions between pages
return MaterialPageRoute(
builder: builder,
settings: settings,
);
},
),
bottomNavigationBar: BottomNavigationBar(
items: <BottomNavigationBarItem>[
BottomNavigationBarItem(
icon: Icon(Icons.mood),
label: 'Page 1',
),
BottomNavigationBarItem(
icon: Icon(Icons.connect_without_contact),
label: 'Page 2',
),
BottomNavigationBarItem(
icon: Icon(Icons.message),
label: 'Page 3',
),
],
currentIndex: _currentPage,
// selectedItemColor: Colors.amber[800],
onTap: (value) {
/// Update page if a different tab from the current was clicked
if (value != _currentPage)
setState(() {
_currentPage = value;
switch (value) {
case 0:
navigationKey.currentState!
.pushReplacementNamed(Pages.page1);
break;
case 1:
navigationKey.currentState!
.pushReplacementNamed(Pages.page2);
break;
case 2:
navigationKey.currentState!
.pushReplacementNamed(Pages.page3);
break;
default:
/// TODO Error 404 page
throw Exception('Invalid route: $value');
}
});
},
),
);
}
Widget _page1() {
return Scaffold(
body: Container(
color: Colors.lightBlueAccent,
child: Center(
child: Text('Page 1'),
),
),
);
}
Widget _page2() {
return Scaffold(
body: Container(
color: Colors.orangeAccent,
child: Center(
child: Text('Page2'),
),
),
);
}
Widget _page3() {
return Scaffold(
body: Container(
color: Colors.lightGreenAccent,
child: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text('Page 3'),
ElevatedButton(onPressed: (){
navigationKey.currentState!.pushNamed(Pages.page4);
}, child: Text('Page 4')),
],
),
),
),
);
}
}
class Page4Screen extends StatefulWidget {
Page4Screen({Key? key, required GlobalKey<NavigatorState> navigatorKey}) : _navigatorKey = navigatorKey, super(key: key);
final GlobalKey<NavigatorState> _navigatorKey;
#override
createState() => Page4State();
}
class Page4State extends State<Page4Screen>{
#override
Widget build(BuildContext context) {
return Scaffold(
// appBar: AppBar(
// title: Text(AppLocalizations.of(context)!.txtTitleMood),
// automaticallyImplyLeading: false,
// ),
body: Container(
color: Colors.redAccent,
child: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text('Page 4'),ElevatedButton(
// Within the SecondScreen widget
onPressed: () {
// Navigate back to the first screen by popping the current route
// off the stack.
widget._navigatorKey.currentState!.pop();
},
child: Text('Go Back!'),
),
],
),
),
),
);
}
}
The Navigator widget does not handle back buttons by default and that's your job to do it if you have defined a Navigator widget. You can catch back press by WillPopScope widget. It takes a Future<bool> Function() which will be called whenever user wants to go back. If it returns false then your default Navigator which lies in MaterialApp will not pop the current route which simply is showing your HomePage in this case. So if your nested navigator has something to pop (like Page4) then it will pop that and will prevent your main Navigator from popping your HomePage.
class _HomeState extends State<HomePage> {
...
#override
Widget build(BuildContext context) {
return WillPopScope(
onWillPop: () async => !(await navigationKey.currentState!.maybePop()),
child: Scaffold(
...
),
);
}
}

Get current route name of CupertinoTabView in Flutter?

I'm using CupertinoTabScaffold and CupertinoTabView to build navigation bottom bar in my App. For one CupertinoTabView I go to others pushed routes name, I would like to get the current name of a CupertinoTabView, but I get Null
I define the routes in main like that
CupertinoApp(
home: MyApp(),
title: 'machin',
routes: appRoutes,)
final appRoutes = {
'/pushedName': (context) => PushedName(),
};
MyApp class //
final GlobalKey<NavigatorState> profileTabNavKey =
GlobalKey<NavigatorState>();
CupertinoTabScaffold(
tabBar: CupertinoTabBar(
activeColor: Color(0xff077018),
border: Border.all(color: Color(0xffffffff)),
currentIndex: widget.currentIndex,
onTap: (index) {},
items: <BottomNavigationBarItem>[....],
),
tabBuilder: (BuildContext context, int index) {
switch (index) {
case 0:
return CupertinoTabView(
navigatorKey: profileTabNavKey,
routes: appRoutes,
builder: (BuildContext context) =>
SettingsView());
break;
default:
return HomePage();
}
},
),
In the SettingsView I pushed a named route by using
Navigator.pushNamed(context, '/pushedName')
I tried to get the route name in the my app class by using
print(ModalRoute.of(profileTabNavKey.currentContext).settings.name);
nb: in the pushedName View i get it perfectly any help , thanks in advance
Just use the BuildContext from the build widget to get the ModalRoute data :
ModalRoute.of(context).settings.name
Working example :
import 'package:flutter/cupertino.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return CupertinoApp(
debugShowCheckedModeBanner: false,
theme: CupertinoTheme.of(context).copyWith(
brightness: Brightness.light,
),
home: MainPage(),
);
}
}
class MainPage extends StatefulWidget {
#override
_MainPageState createState() => _MainPageState();
}
class _MainPageState extends State<MainPage> {
int currentIndex = 0;
#override
Widget build(BuildContext context) {
return CupertinoTabScaffold(
tabBar: CupertinoTabBar(
currentIndex: currentIndex,
onTap: (index) {
setState(() {
currentIndex = index;
});
},
items: <BottomNavigationBarItem>[
BottomNavigationBarItem(
label: 'Home',
icon: Icon(CupertinoIcons.home),
),
BottomNavigationBarItem(
label: 'Setting',
icon: Icon(CupertinoIcons.settings),
),
],
),
tabBuilder: (BuildContext context, int index) {
switch (index) {
case 1:
return CupertinoTabView(
routes: <String, WidgetBuilder>{
'/setting': (context) => SettingsPage(),
'/setting/2': (context) => SettingsPage(2),
'/setting/2/3': (context) => SettingsPage(3),
},
builder: (context) => SettingsPage(),
);
break;
default:
return Center(
child: Text('Home page'),
);
}
},
);
}
}
class SettingsPage extends StatelessWidget {
final int index;
SettingsPage([this.index = 1]);
#override
Widget build(BuildContext context) {
// here we go to get the current route name
print(ModalRoute.of(context).settings.name);
return CupertinoPageScaffold(
navigationBar: CupertinoNavigationBar(
backgroundColor: CupertinoColors.systemGrey.withOpacity(0.5),
middle: Text(index > 1 ? 'Settings page - $index' : 'Settings page'),
),
child: Center(
child: CupertinoButton.filled(
child: Text('Go'),
onPressed: () {
if (index == 1) {
Navigator.pushNamed(context, '/setting/2');
} else if (index == 2) {
Navigator.pushNamed(context, '/setting/2/3');
}
},
),
),
);
}
}
Go to Dartpad
I found a solution that doesn't sound like best practice, but it works!
Instead of using ModalRouter and other libraries like navigation_history_observer, I used Navigator.popUntil and blocked the popup from getting the current route from the argument and assigned it to a variable.
WillPopScope(
onWillPop: () async {
String currentRoute;
navigatorKeys[_tabController.index].currentState.popUntil((route) {
currentRoute = route.settings.name;
return true;
});
if (currentRoute == '/') {
return Future.value(false);
} else {
return !await navigatorKeys[_tabController.index]
.currentState
.maybePop();
}
},
// ...
);

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

Bottom tab navigator show up when I click back button from my phone in flutter

Hi I am new in flutter and right now I try to declare my data for all tabs with this code, but when I click tab, the bottom navigator is dismiss and show up again when I click back button from my phone, is there anyone know the mistakes or the problems?
class BottomTab extends StatefulWidget {
final String text;
BottomTab({this.text});
#override
_BottomTabState createState() => _BottomTabState();
}
class _BottomTabState extends State<BottomTab> {
void initState() {
super.initState();
}
_onTap(int index) {
setState(() => _selectedIndex = index);
if (index == 0) {
Navigator.push(
context,
new MaterialPageRoute(
builder: (BuildContext context) =>
new HomeScreen(value: widget.value)));
} else if (index == 1) {
Navigator.push(
context,
new MaterialPageRoute(
builder: (BuildContext context) =>
new FirstPage(value: widget.value)));
} else {
Navigator.push(
context,
new MaterialPageRoute(
builder: (BuildContext context) =>
new HomeScreen(value: widget.value)));
}
}
final List<Widget> pages = [
HomeScreen(),
FirstPage(),
];
final PageStorageBucket bucket = PageStorageBucket();
int _index = 0;
Widget _myList(int index) => BottomNavigationBar(
onTap: _onTap,
currentIndex: index,
items: const <BottomNavigationBarItem>[
BottomNavigationBarItem(icon: Icon(Icons.home), title: Text('Home')),
BottomNavigationBarItem(icon: Icon(Icons.more), title: Text('More')),
],
);
#override
Widget build(BuildContext context) {
return Scaffold(
bottomNavigationBar: _myList(_index),
body: PageStorage(
child: pages[_index],
bucket: bucket,
),
);
}
}
You can copy paste run full code below
In your case, you do not need Navigator.push and change this line
From
setState(() => _selectedIndex = index);
To
setState(() => _index = index);
working demo
full code
import 'package:flutter/material.dart';
class BottomTab extends StatefulWidget {
final String text;
BottomTab({this.text});
#override
_BottomTabState createState() => _BottomTabState();
}
class _BottomTabState extends State<BottomTab> {
void initState() {
super.initState();
}
_onTap(int index) {
setState(() => _index = index);
/*if (index == 0) {
Navigator.push(
context,
new MaterialPageRoute(
builder: (BuildContext context) =>
new HomeScreen(value: widget.value)));
} else if (index == 1) {
Navigator.push(
context,
new MaterialPageRoute(
builder: (BuildContext context) =>
new FirstPage(value: widget.value)));
} else {
Navigator.push(
context,
new MaterialPageRoute(
builder: (BuildContext context) =>
new HomeScreen(value: widget.value)));
}*/
}
final List<Widget> pages = [
HomeScreen(),
FirstPage(),
];
final PageStorageBucket bucket = PageStorageBucket();
int _index = 0;
Widget _myList(int index) => BottomNavigationBar(
onTap: _onTap,
currentIndex: index,
items: const <BottomNavigationBarItem>[
BottomNavigationBarItem(icon: Icon(Icons.home), title: Text('Home')),
BottomNavigationBarItem(icon: Icon(Icons.more), title: Text('More')),
],
);
#override
Widget build(BuildContext context) {
return Scaffold(
bottomNavigationBar: _myList(_index),
body: PageStorage(
child: pages[_index],
bucket: bucket,
),
);
}
}
class HomeScreen extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("demo"),
),
body: Text("HomesScreen"));
}
}
class FirstPage extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("demo"),
),
body: Text("FirstPage"));
}
}
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: BottomTab(),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
int _counter = 0;
void _incrementCounter() {
setState(() {
_counter++;
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
'You have pushed the button this many times:',
),
Text(
'$_counter',
style: Theme.of(context).textTheme.headline4,
),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: _incrementCounter,
tooltip: 'Increment',
child: Icon(Icons.add),
),
);
}
}