How to toggle visibility of TabBar with Bottom Navigation Items in Flutter - flutter

I have a bottomNavigationBar and an AppBar in my flutter app. At the bottom of the AppBar is a TabBar consisting of two items. So I want the TabBar to be invisible when some items of the BottomNavigationBar is clicked. I tried to assign the Visibility class to my TabBar with a Boolean variable but it doesn't work. It seems like I can't handle the TabBar widget separately.
How do resolve this?
class DashBoardPage extends StatefulWidget {
#override
_DashBoardPageState createState() => _DashBoardPageState();
}
class _DashBoardPageState extends State<DashBoardPage> {
SharedPreferences sharedPreferences;
bool showTabs = false;
int tabsIndex = 0;
int _currentIndex = 0;
String _appBarText = "Welcome, User";
Widget callPage(int currentIndex) {
switch (currentIndex) {
case 0:
showTabs = true;
_appBarText = "Welcome, User";
return TabBarView(
children:[
new HomePage(),
new SchedulePage()
]
);
break;
case 1:
showTabs = false;
break;
case 2:
showTabs = false;
break;
default:
return HomePage();
}
}
#override
void initState() {
super.initState();
checkLoginState();
}
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'MAF Mentor',
debugShowCheckedModeBanner: false,
home: DefaultTabController(
length: choices.length,
child: Scaffold(
appBar: AppBar(
backgroundColor: Color(0xFFFFFFFF),
title: Text(
_appBarText,
style: TextStyle(
color: Color(0xFF1C2447),
fontFamily: 'Muli',
fontSize: 16.0,
),
),
bottom: showTabs? TabBar(
isScrollable: true,
tabs: choices.map<Widget>((Choice choice) {
return Tab(
text: choice.title,
icon: Icon(choice.icon),
);
}).toList(),
labelColor: Color(0xFF1C2447),
):null,
actions: <Widget>[
IconButton(
icon: Icon(
Icons.account_circle,
color: Color(0xFF1C2447),
),
onPressed: () {
Navigator.of(context).pushNamed('/profile_page');
},
),
IconButton(
icon: Icon(
Icons.notifications,
color: Color(0xFF1C2447),
),
onPressed: () {
// do something
},
),
],
), //AppBar
body: callPage(_currentIndex),
bottomNavigationBar: BottomNavigationBar(
showSelectedLabels: false,
showUnselectedLabels: false,
fixedColor: Color(0xFF1C2447),
currentIndex: _currentIndex,
onTap: (value) {
_currentIndex = value;
callPage(_currentIndex);
setState(() {
});
},
items: [
BottomNavigationBarItem(
icon: Icon(Icons.home), title: Text("Bar 1")),
BottomNavigationBarItem(
icon: Icon(Icons.people), title: Text("Bar 2")),
BottomNavigationBarItem(
icon: Icon(Icons.history), title: Text("Bar 3"))
],
),
),
),
);
}

bottom requires a PreferredSizeWidget so you can not use the Visibility widget there. You can use a boolean variable to do that. You can see the whole code below. Since I don't know your choices and tabs I randomly put something. But the idea is if you want to show TabBar when user tap BottomNavigationBarItem
number 1 you just update your boolean variable as true. Otherwise make it false.
class TabBarExample extends StatefulWidget {
#override
_TabBarExampleState createState() => _TabBarExampleState();
}
class _TabBarExampleState extends State<TabBarExample> {
bool showTabs = false;
int selectedIndex = 0;
#override
Widget build(BuildContext context) {
return DefaultTabController(
length: 2,
child: Scaffold(
appBar: AppBar(
backgroundColor: Color(0xFFFFFFFF),
title: Text(
'_appBarText',
style: TextStyle(
color: Color(0xFF1C2447),
fontFamily: 'Muli',
fontSize: 16.0,
),
),
bottom: showTabs
? TabBar(
isScrollable: true,
tabs: <Widget>[
Tab(
text: 'Choice1',
icon: Icon(Icons.add_circle_outline),
),
Tab(
text: 'Choice1',
icon: Icon(Icons.add_circle),
),
],
labelColor: Color(0xFF1C2447),
)
: null,
),
bottomNavigationBar: BottomNavigationBar(
currentIndex: selectedIndex,
items: [
BottomNavigationBarItem(
icon: Icon(Icons.home), title: Text('first')),
BottomNavigationBarItem(
icon: Icon(Icons.favorite), title: Text('second')),
],
onTap: (index) {
if (index == 1) {
setState(() => showTabs = true);
} else {
setState(() => showTabs = false);
}
setState(() => selectedIndex = index);
},
),
),
);
}
}

Related

how to access PageViewController outside of widget

TabScreen is my main widget in my app that includes a BottomNavigationBar and a PageView to transition between pages.
PageController allows me to change views and everything is fine here, but there is one thing missing. How can I change my PageView controller outside of TabScreen? I'd like to put a button to access my main PageView controller from within my pages.
class _TabsScreenState extends State<TabsScreen> {
bool _isloading = true;
int? _selectedIndex;
List<Widget>? _pages = [
HomeScreen(),
CurrenPlanDetail(),
Container(),
ProfileScreen(),
SettingScreens(),
];
PageController? _pageController;
#override
void initState() {
_selectedIndex = 0;
_pageController = PageController(initialPage: _selectedIndex!);
}
}
Widget build(BuildContext context) {
return Scaffold(
body: PageView(
controller: _pageController,
children: _pages!,
physics: NeverScrollableScrollPhysics(),
),
bottomNavigationBar: Visibility(
visible: !_isloading,
child: BottomNavigationBar(
type: BottomNavigationBarType.fixed,
selectedItemColor: kNewPurple,
//unselectedItemColor: Colors.grey,
currentIndex: _selectedIndex!,
onTap: (value) {
setState(() {
_selectedIndex = value;
_pageController!.jumpToPage(_selectedIndex!);
});
},
backgroundColor: Colors.grey[300],
items: [
BottomNavigationBarItem(
icon: Icon(
Ionicons.home_outline,
size: 15.sp,
),
label: 'Home'),
BottomNavigationBarItem(
icon: Icon(
Ionicons.reader_outline,
size: 15.sp,
),
label: 'Plan'),
BottomNavigationBarItem(
icon: ElevatedButton(
style: ElevatedButton.styleFrom(
shape: CircleBorder(),
fixedSize: Size(50, 50),
),
onPressed: () {
showModalBottomSheet(
context: context,
builder: (context) {
return FloatingButton();
});
},
child: Icon(Ionicons.add)),
label: ''),
BottomNavigationBarItem(
icon: Icon(
Ionicons.happy_outline,
size: 15.sp,
),
label: 'Profile'),
BottomNavigationBarItem(
icon: Icon(
Ionicons.settings_outline,
size: 15.sp,
),
label: 'Setting'),
],
),
),
);
}
}
for example, somewhere in my app, I'd like to put a button and pass a function like this :
_pageController!.jumpToPage(1);
Define PageController as static and
TabScreen.pageController.jumpToPage(1);

Flutter BottomNavigationBar stackoverflow

i'm starting with Flutter and i'm struggling with the navigationBar, if i add the body i keep getting a stackOverflow.
If i don't add the body everything is fine.
Error:
The following StackOverflowError was thrown building DefaultTextStyle(debugLabel: (englishLike body1 2014).merge(blackMountainView bodyText2), inherit: false, color: Color(0xdd000000), family: Roboto, size: 14.0, weight: 400, baseline: alphabetic, decoration: TextDecoration.none, softWrap: wrapping at box width, overflow: clip):
Stack Overflow
The relevant error-causing widget was:
Scaffold Scaffold:file:///Users/salvatorelafiura/git/energy_flutter/lib/screen/main.dart:104:12
When the exception was thrown, this was the stack:
#0 new Uint8List (dart:typed_data-patch/typed_data_patch.dart:2201:3)
#1 _createTables.<anonymous closure> (dart:core/uri.dart:3872:60)
#2 new _GrowableList.generate (dart:core-patch/growable_array.dart:133:28)
Code of the current widget, 3 screens one bottomNavigation.
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widgetTitle.elementAt(selectedIndex)),
actions: <Widget>[
IconButton(
icon: const Icon(
Icons.logout,
color: Colors.white,
),
onPressed: () {
signOut();
},
)
],
),
body: Center(
child: IndexedStack(index: selectedIndex, children: tabPages),
),
bottomNavigationBar: BottomNavigationBar(
items: const <BottomNavigationBarItem>[
BottomNavigationBarItem(icon: Icon(Icons.home), label: "Pratica"),
BottomNavigationBarItem(icon: Icon(Icons.mail), label: "Messages"),
BottomNavigationBarItem(icon: Icon(Icons.person), label: "Profilo"),
],
currentIndex: selectedIndex,
onTap: onItemTapped,
backgroundColor: Colors.white,
fixedColor: Colors.blue,
selectedLabelStyle: const TextStyle(color: Colors.red, fontSize: 20),
unselectedFontSize: 16,
selectedIconTheme:
const IconThemeData(color: Colors.blue, opacity: 1.0, size: 30.0),
unselectedItemColor: Colors.grey,
unselectedLabelStyle: const TextStyle(fontSize: 18, color: Colors.pink),
), // This trailing comma makes auto-formatting nicer for build methods.
);
}
Create a Separate Class "Bottom" and Place the whole code of your Bottomnavigationbar inside that class then at every Screen just Call inside the Scaffold like:
bottomNavigationBar: Bottom();
Then Declare your int selectedIndex = 0; Globally
it will works fine.
Modify the Given code:
import 'package:flutter/material.dart';
int _selectedIndex = 0;
class Bottom extends StatefulWidget {
#override
_BottomState createState() => _BottomState();
}
class _BottomState extends State<Bottom> {
#override
Widget build(BuildContext context) {
return BottomNavigationBar(
showSelectedLabels: true, // <-- HERE
showUnselectedLabels: true,
backgroundColor: Color(0xff38547C),
type: BottomNavigationBarType.fixed,
currentIndex: _selectedIndex,
selectedItemColor: Color(0xFF1C2834),
unselectedItemColor: Colors.white,
items: [
BottomNavigationBarItem(
icon: const Icon(
Icons.home,
),
label: "Home",
),
BottomNavigationBarItem(
icon: ImageIcon(
AssetImage("assets/images/ball.png"),
),
label: "Matches",
),
BottomNavigationBarItem(
icon: const Icon(
Icons.live_tv,
),
label: "Live"),
BottomNavigationBarItem(
icon: Icon(
Icons.poll,
),
label: "Ranking"),
BottomNavigationBarItem(
icon: Icon(
Icons.more_horiz,
),
label: "More"),
],
onTap: (int index) {
setState(() {
_selectedIndex = index;
});
if (_selectedIndex == 0) {
var route =
MaterialPageRoute(builder: (BuildContext context) => Home());
Navigator.of(context).push(route);
} else if (_selectedIndex == 1) {
var route =
MaterialPageRoute(builder: (BuildContext context) => Matches());
Navigator.of(context).push(route);
} else if (_selectedIndex == 2) {
var route =
MaterialPageRoute(builder: (BuildContext context) => Live());
Navigator.of(context).push(route);
} else if (_selectedIndex == 3) {
var route =
MaterialPageRoute(builder: (BuildContext context) => Ranking());
Navigator.of(context).push(route);
} else if (_selectedIndex == 4) {
var route =
MaterialPageRoute(builder: (BuildContext context) => More());
Navigator.of(context).push(route);
}
});
}
}

Flutter - using routes in bottomnavigationbar

Im trying to navigate to next page via switch index, but it doesn't work.
Does anyone knows how should I use switch case? thank you
Below is my code:
child: BottomNavigationBar(
items: <BottomNavigationBarItem>[
BottomNavigationBarItem(
icon: _selectedIndex == 0
? SvgPicture.asset('assets/icons/home_colored.svg')
: SvgPicture.asset('assets/icons/home.svg'),
title: Text('Home', style: bottomTextStyle),
),
BottomNavigationBarItem(
icon: _selectedIndex == 1
? SvgPicture.asset('assets/icons/order_colored.svg')
: SvgPicture.asset('assets/icons/order.svg'),
title: Text(
'My Card',
style: bottomTextStyle,
),
),
BottomNavigationBarItem(
icon: _selectedIndex == 2
? SvgPicture.asset('assets/icons/watch_colored.svg')
: SvgPicture.asset('assets/icons/watch.svg'),
title: Text(
'Watch List',
style: bottomTextStyle,
),
),
BottomNavigationBarItem(
icon: _selectedIndex == 3
? SvgPicture.asset('assets/icons/account_colored.svg')
: SvgPicture.asset('assets/icons/account.svg'),
title: Text(
'Account',
style: bottomTextStyle,
),
),
In the below code "HomeScreen()" and "NotificationHome()" are the class name to which we need to navigate on tap."
class Bottom_Nav extends StatefulWidget {
const Bottom_Nav({Key? key}) : super(key: key);
#override
_Bottom_NavState createState() => _Bottom_NavState();
}
class _Bottom_NavState extends State<Bottom_Nav> {
int selectedPage = 0;
final _pageOptions = [
const HomeScreen(),
//const searchHome(),
NotificationHome(),
];
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.white,
body: _pageOptions[selectedPage],
bottomNavigationBar: BottomNavigationBar(
items: [
BottomNavigationBarItem(
icon: Icon(Icons.home, size: 30), label: ('Home')),
BottomNavigationBarItem(
icon: Badge(
badgeContent: Text('3'),
child: Icon(Icons.notifications, size: 30)),
label: ("Notification")),
],
selectedItemColor: bottomBarSelected,
elevation: 5.0,
unselectedItemColor: bottomBarNotSelected,
currentIndex: selectedPage,
backgroundColor: Colors.white,
onTap: (index) {
setState(() {
selectedPage = index;
});
},
));
}
}
Comment if you have any doubt,
Thank you.
Try below code hope its help to you just add your images or icons instead of my answer Icons :
Go for documentation here
BottomNavigationBar(
items: <BottomNavigationBarItem>[
BottomNavigationBarItem(
icon: _selectedIndex == 0 ? Icon(Icons.home) : Icon(Icons.add),
label: 'Home',
),
BottomNavigationBarItem(
icon: _selectedIndex == 1 ? Icon(Icons.business) : Icon(Icons.person),
label: 'Business',
),
BottomNavigationBarItem(
icon: _selectedIndex == 2 ? Icon(Icons.school) : Icon(Icons.close),
label: 'School'
),
],
currentIndex: _selectedIndex,
selectedItemColor: Colors.amber[800],
onTap: _onItemTapped,
),
Your result screen when your index is 0 ->
Your result screen when your index is 1 ->
Solution!
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
/// This Widget is the main application widget.
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
home: MyNavigationBar (),
);
}
}
class MyNavigationBar extends StatefulWidget {
MyNavigationBar ({Key key}) : super(key: key);
#override
_MyNavigationBarState createState() => _MyNavigationBarState();
}
class _MyNavigationBarState extends State<MyNavigationBar> {
int _selectedIndex = 0;
static const List<Widget> _widgetOptions = <Widget>[
Text('Home Page', style: TextStyle(fontSize: 35, fontWeight: FontWeight.bold)),
Text('Search Page', style: TextStyle(fontSize: 35, fontWeight: FontWeight.bold)),
Text('Profile Page', style: TextStyle(fontSize: 35, fontWeight: FontWeight.bold)),
];
void _onItemTapped(int index) {
setState(() {
_selectedIndex = index;
if(__selectedIndex == 0){
Navigator.push(
context,
MaterialPageRoute(builder: (context) => secondPage()),
);
} else if (__selectedIndex == 1){
Navigator.push(
context,
MaterialPageRoute(builder: (context) => thirdPage()),
);
} else if (__selectedIndex == 2){
Navigator.push(
context,
MaterialPageRoute(builder: (context) => fourthPage()),
);
} else if (__selectedIndex == 3){
Navigator.push(
context,
MaterialPageRoute(builder: (context) => firstPage()),
);
}
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Flutter BottomNavigationBar Example'),
backgroundColor: Colors.green
),
body: Center(
child: _widgetOptions.elementAt(_selectedIndex),
),
bottomNavigationBar: BottomNavigationBar(
items: <BottomNavigationBarItem>[lĖĨ
BottomNavigationBarItem(
icon: _selectedIndex == 0
? SvgPicture.asset('assets/icons/home_colored.svg')
: SvgPicture.asset('assets/icons/home.svg'),
title: Text('Home', style: bottomTextStyle),
),
BottomNavigationBarItem(
icon: (_selectedIndex == 1)
? SvgPicture.asset('assets/icons/order_colored.svg')
: SvgPicture.asset('assets/icons/order.svg'),
title: Text(
'My Card',
style: bottomTextStyle,
),
),
BottomNavigationBarItem(
icon: (_selectedIndex == 2)
? SvgPicture.asset('assets/icons/watch_colored.svg')
: SvgPicture.asset('assets/icons/watch.svg'),
title: Text(
'Watch List',
style: bottomTextStyle,
),
),
BottomNavigationBarItem(
icon: (_selectedIndex == 3)
? SvgPicture.asset('assets/icons/account_colored.svg')
: SvgPicture.asset('assets/icons/account.svg'),
title: Text(
'Account',
style: bottomTextStyle,
),
),
],
type: BottomNavigationBarType.shifting,
currentIndex: _selectedIndex,
selectedItemColor: Colors.black,
iconSize: 40,
onTap: _onItemTapped,
elevation: 5
),
);
}
}
Replace secondPage(), thirdPage(), fourthPage(), firstPage() with class names to which you want to navigate and provide arguments if you have any?..
example: secondPage('Second Page Title')
Comment if you have any doubts, Thank you.

Flutter - appbar bottom property not updating properly with setState

I'm building an app with an appbar that has the bottom property that will only be visible if the user selects the middle item of the 3 items (item index = 1) in the bottom navigation bar. here's the code below.
class _MainPageState extends State<MainPage> {
int index = 2;
TabBar bottomBar = null;
#override
Widget build(BuildContext context) => DefaultTabController(
initialIndex: 0,
length: 3,
child: Scaffold(
appBar: AppBar(title: Text(widget.title), bottom: bottomBar),
bottomNavigationBar: BottomNavigationBar(
currentIndex: index,
selectedItemColor: Colors.teal,
items: [
BottomNavigationBarItem(
icon: Icon(Icons.bolt),
label: ('Devices'),
),
BottomNavigationBarItem(
icon: Icon(Icons.pie_chart),
label: ('Cluster'),
),
BottomNavigationBarItem(
icon: Icon(Icons.settings),
label: ('Settings'),
),
],
onTap: (int index) => setState(() => this.index = index),
),
body: buildPages(),
),
);
Widget buildPages() {
// bottomNavBarPageBuilder
switch (index) {
case 0:
setState(() {
this.bottomBar = null;
print(index);
});
return DeviceListPage();
case 1:
setState(() {
print(index);
this.bottomBar = TabBar(
tabs: [
Tab(
icon: Icon(Icons.power),
),
Tab(
icon: Icon(Icons.power),
),
Tab(
icon: Icon(Icons.power),
)
],
);
});
return TabBarView(
children: [UserLocalPage(), Container(), Container()]);
case 2:
setState(() {
print(index);
this.bottomBar = null;
});
return SettingsPage();
default:
setState(() {
print(index);
this.bottomBar = null;
});
return Container();
}
}
}
the problem is that sometimes the setState doesn't update the "bottom" property of the appBar. here's a video demonstrating the problem
how can I make the bottom property of the appBar be updated properly? any help would be much appreciated thankyou 🙏🙏
Sorry for a late answer. Would you kindly try this code for me?
Also, although I didn't change that in the code below, I noticed that your index == 2, but initialIndex == 0. I would recommend creating a const variable to represent initialIndex, like this:
static const int initialIndex = 0;
int index = initialIndex;
//skipped code
initialIndex: initialIndex,
class _MainPageState extends State<MainPage> {
int index = 2;
TabBar bottomBar = null;
#override
Widget build(BuildContext context) => DefaultTabController(
initialIndex: 0,
length: 3,
child: Scaffold(
appBar: AppBar(title: Text(widget.title), bottom: bottomBar),
bottomNavigationBar: BottomNavigationBar(
currentIndex: index,
selectedItemColor: Colors.teal,
items: [
BottomNavigationBarItem(
icon: Icon(Icons.bolt),
label: ('Devices'),
),
BottomNavigationBarItem(
icon: Icon(Icons.pie_chart),
label: ('Cluster'),
),
BottomNavigationBarItem(
icon: Icon(Icons.settings),
label: ('Settings'),
),
],
onTap: _onTap,
),
body: buildPages(),
),
);
void _onTap(int index) {
if(index != this.index) {
setState(() {
this.index = index;
switch(index) {
case 1:
bottomBar = TabBar(
tabs: [
Tab(
icon: Icon(Icons.power),
),
Tab(
icon: Icon(Icons.power),
),
Tab(
icon: Icon(Icons.power),
)
],
);
break;
default:
bottomBar = null;
}
});
}
}
Widget buildPages() {
// bottomNavBarPageBuilder
switch (index) {
case 0:
return DeviceListPage();
case 1:
return TabBarView(
children: [UserLocalPage(), Container(), Container()]);
case 2:
return SettingsPage();
default:
return Container();
}
}
}

How to conditionally show bottom navigation bar when changing upper tab bar in flutter

I have the following test screen on my app:
As seen, my intention is that I will have 3 widgets connected to each upper tab. And I also want to have a bottom navigation bar but I only want it to be visible when the user is under Upper Tab 3. For instance, the user is under Upper Tab 1 in the screenshot above but the bottom navigation bar is still visible.
Here is my code that I have written to achieve this but it just does not work. I keep seeing the bottom navigation bar no matter under which upper tab bar I am. What am I supposed to do to achieve that my bottom navigation bar is only seen when the user is under Upper Tab 3 tab bar?
import 'package:flutter/material.dart';
class TestPage extends StatefulWidget {
#override
_TestPageState createState() => _TestPageState();
}
class _TestPageState extends State<TestPage>
with AutomaticKeepAliveClientMixin {
#override
void initState() {
super.initState();
}
#override
bool get wantKeepAlive => true;
int _currentBottomBarIndex = 0;
bool _showBottomBar = false;
final _tabs = [
Center(child: Text('Bottom Tab 1')),
Center(child: Text('Bottom Tab 2')),
];
Widget _changeUpperTab(upperTabIdx, isBottomBar) {
setState(() {
_showBottomBar = isBottomBar;
});
if (_showBottomBar) {
return _tabs[_currentBottomBarIndex];
} else {
return Center(child: Text('Tab ' + upperTabIdx.toString()));
}
}
#override
Widget build(BuildContext context) {
super.build(context);
return DefaultTabController(
length: 3,
child: Scaffold(
appBar: AppBar(
title: Text('Test App'),
bottom: TabBar(
indicatorColor: Colors.white,
tabs: [
Tab(
child: Text(
'Upper Tab 1',
style: TextStyle(fontWeight: FontWeight.bold),
)),
Tab(
child: Text(
'Upper Tab 2',
style: TextStyle(fontWeight: FontWeight.bold),
)),
Tab(
child: Text(
'Upper Tab 3',
style: TextStyle(fontWeight: FontWeight.bold),
)),
],
),
),
body: TabBarView(
children: [
_changeUpperTab(1, false),
_changeUpperTab(2, false),
_changeUpperTab(3, true),
],
),
bottomNavigationBar: (_showBottomBar)
? BottomNavigationBar(
currentIndex: _currentBottomBarIndex,
items: [
BottomNavigationBarItem(
icon: Icon(Icons.search),
label: 'Search',
backgroundColor: Colors.yellow),
BottomNavigationBarItem(
icon: Icon(Icons.home),
label: 'Home',
backgroundColor: Colors.red),
],
onTap: (index) {
setState(() {
_currentBottomBarIndex = index;
});
},
)
: null,
),
);
}
}
You can use this code to create it in the tab you want, but i would recommend you to create a separate statelessWidget for that tab and you can have it more organized.
class TestPage extends StatefulWidget {
#override
_TestPageState createState() => _TestPageState();
}
class _TestPageState extends State<TestPage>
with AutomaticKeepAliveClientMixin {
#override
void initState() {
super.initState();
}
#override
bool get wantKeepAlive => true;
int _currentBottomBarIndex = 0;
bool _showBottomBar = false;
final _tabs = [
Center(child: Text('Bottom Tab 1')),
Center(child: Text('Bottom Tab 2')),
];
Widget _changeUpperTab(upperTabIdx, isBottomBar) {
setState(() {
_showBottomBar = isBottomBar;
});
if (_showBottomBar) {
return Scaffold(
body: _tabs[_currentBottomBarIndex],
bottomNavigationBar: BottomNavigationBar(
currentIndex: _currentBottomBarIndex,
items: [
BottomNavigationBarItem(
icon: Icon(Icons.search),
label: 'Search',
backgroundColor: Colors.yellow),
BottomNavigationBarItem(
icon: Icon(Icons.home),
label: 'Home',
backgroundColor: Colors.red),
],
onTap: (index) {
setState(() {
_currentBottomBarIndex = index;
});
},
),
);
} else {
return Center(child: Text('Tab ' + upperTabIdx.toString()));
}
}
#override
Widget build(BuildContext context) {
super.build(context);
return DefaultTabController(
length: 3,
child: Scaffold(
appBar: AppBar(
title: Text('Test App'),
bottom: TabBar(
indicatorColor: Colors.white,
tabs: [
Tab(
child: Text(
'Upper Tab 1',
style: TextStyle(fontWeight: FontWeight.bold),
)),
Tab(
child: Text(
'Upper Tab 2',
style: TextStyle(fontWeight: FontWeight.bold),
)),
Tab(
child: Text(
'Upper Tab 3',
style: TextStyle(fontWeight: FontWeight.bold),
)),
],
),
),
body: TabBarView(
children: [
_changeUpperTab(1, false),
_changeUpperTab(2, false),
_changeUpperTab(3, true),
],
),
),
);
}
}