How to add Tabs Top side and Bottom side both in flutter - flutter

Top Tabs Shows Only HomePage and they show 3 different page via Scrolling or tapping, and bottom tabs for whole Apps like menu.
when i code written then i get views like below images, but i cant tap or redirect page.
navigation code i only given top or bottom tabs not both tabs.
homePage.dart
class _HomePageState extends State<HomePage> with SingleTickerProviderStateMixin {
TabController tabController;
//TabController bottomController;
Icon searchBtn = new Icon(Icons.search);
Widget appBarTitle = new Text('Invoices');
#override
void initState(){
super.initState();
tabController = new TabController(vsync: this, length: 3);
//bottomController = new TabController(vsync: this, length: 4);
}
#override
void dispose(){
tabController.dispose();
//bottomController.dispose();
super.dispose();
}
#override
Widget build(BuildContext context) {
return new MaterialApp(
color: Colors.purpleAccent,
debugShowCheckedModeBanner: false,
home: DefaultTabController(
length: 3,
child:Scaffold(
appBar: new AppBar(
centerTitle: false,
title: appBarTitle,
backgroundColor: Color(0xFF832685),
actions: <Widget>[
new IconButton(
icon: searchBtn,
onPressed: (){
setState(() {
if(this.searchBtn.icon == Icons.search){
this.searchBtn = new Icon(Icons.close);
this.appBarTitle = new TextField(
style: new TextStyle(
color: Colors.white,
),
decoration: new InputDecoration(
//fillColor: Colors.white,
border: InputBorder.none,
// focusedBorder: OutlineInputBorder(
// borderRadius: BorderRadius.all(Radius.circular(5.0)),
// borderSide: BorderSide(color: Colors.white)),
filled: true,
prefixIcon: new Icon(Icons.search,
color: Colors.white),
hintText: "Search...",
hintStyle: new TextStyle(color: Colors.white),
),
);
}
else{
this.searchBtn = new Icon(Icons.search);
this.appBarTitle = new Text('Invoices');
}
});
},
)
],
bottom: new TabBar(
indicatorColor: Color(0xFF832685),
controller: tabController,
tabs: <Tab>[
new Tab(text: 'Unpaid'.toUpperCase(),),
new Tab(text: 'Draft'.toUpperCase(),),
new Tab(text: 'All'.toUpperCase(),),
],
),
),
//bottomNavigationBar: BottomNavBar(),
//bottomNavigationBar: _BottomBar(),
// bottomNavigationBar: new TabBar(
// indicatorColor: Color(0xFF832685),
// labelColor: Color(0xFF832685),
// //controller: bottomController,
// tabs: <Tab>[
// new Tab(icon: new Icon(Icons.home),text: 'Home',),
// new Tab(icon: new Icon(Icons.home),text: 'Home',),
// new Tab(icon: new Icon(Icons.home),text: 'Home',),
// new Tab(icon: new Icon(Icons.home),text: 'Home',),
// ],
// ),
body: new TabBarView(
controller: tabController,
children: <Widget>[
new first.UnpaidInvoicePage(),
new second.PaidInvoicePage(),
new third.AllInvoicePage(),
],
),
//body: Container(),
floatingActionButton: FloatingActionButton(
child: Icon(Icons.add),
tooltip: 'New Invoice',
backgroundColor: Color(0xFF832685),
onPressed: (){
//Navigator.of(context).pushNamed('NewInvoicePage');
Navigator.push(context, MaterialPageRoute(builder: (context) => NewInvoicePage()));
},
),
),
),
);
}
}
Thank you !

Try this
import 'package:flutter/material.dart';
void main() => runApp(HomeScreen());
class HomeScreen extends StatefulWidget {
#override
_HomeScreenPage createState() => _HomeScreenPage();
}
class _HomeScreenPage extends State<HomeScreen>
with SingleTickerProviderStateMixin {
TabController tabController;
String title = "Home";
#override
void initState() {
super.initState();
tabController = new TabController(length: 3, vsync: this);
}
#override
void dispose() {
tabController.dispose();
super.dispose();
}
#override
Widget build(BuildContext context) {
// TODO: implement build
return MaterialApp(
theme: ThemeData(
primarySwatch: Colors.purple,
brightness: Brightness.light,
accentColor: Colors.red),
darkTheme: ThemeData(
brightness: Brightness.dark,
),
home: new Scaffold(
appBar: AppBar(
title: Text(title),
centerTitle: true,
),
body: TabBarView(
children: <Widget>[
FirstTab(),
MyBody("Page Two"),
MyBody("Page Three")
],
// if you want yo disable swiping in tab the use below code
// physics: NeverScrollableScrollPhysics(),
controller: tabController,
),
bottomNavigationBar: Material(
color: Colors.purple,
child: TabBar(
onTap: (indedx) {
if (indedx == 0) {
setState(() {
title = "Home";
});
} else if (indedx == 1) {
setState(() {
title = "Tab Two";
});
} else if (indedx == 2) {
setState(() {
title = "Tab Three";
});
}
},
indicatorColor: Colors.blue,
unselectedLabelColor: Colors.grey,
tabs: <Widget>[
Tab(
icon: Icon(Icons.favorite_border),
text: "ONE",
),
Tab(
icon: Icon(Icons.favorite),
text: "TWO",
),
Tab(
icon: Icon(Icons.add_box),
text: "THREE",
),
],
controller: tabController,
),
),
));
}
}
class FirstTab extends StatefulWidget {
#override
FirstTabState createState() => FirstTabState();
}
class FirstTabState extends State<FirstTab>
with SingleTickerProviderStateMixin {
TabController tabController;
#override
void initState() {
super.initState();
tabController = new TabController(length: 3, vsync: this);
}
#override
void dispose() {
tabController.dispose();
super.dispose();
}
#override
Widget build(BuildContext context) {
// TODO: implement build
return DefaultTabController(
length: 3,
child: Scaffold(
appBar: PreferredSize(
preferredSize: Size.fromHeight(kToolbarHeight),
child: Container(
height: 50.0,
child: new TabBar(
indicatorColor: Colors.blue,
unselectedLabelColor: Colors.grey,
labelColor: Colors.blue,
tabs: [
Tab(
text: "ONE",
),
Tab(
text: "TWO",
),
Tab(
text: "THREE",
),
],
),
),
),
body: TabBarView(
children: [
Text("TAB ONE CONTENT"),
Text("TAB TWO CONTENT"),
Text("TAB THREE CONTENT"),
],
),
),
);
}
}
class MyBody extends StatelessWidget {
final String title;
MyBody(this.title);
final mySnackBar = SnackBar(
content: Text(
"Hello There!",
style: TextStyle(color: Colors.white),
),
duration: Duration(seconds: 3),
backgroundColor: Colors.blue,
);
#override
Widget build(BuildContext context) {
// TODO: implement build
return Container(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
RaisedButton(
child: Text(title + " Click me"),
onPressed: () => {Scaffold.of(context).showSnackBar(mySnackBar)}),
],
),
);
}
}
OUTPUT

void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
// This widget is the root of your application.
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: HomePage(),
);
}
}
class HomePage extends StatefulWidget {
#override
_HomePageState createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> with SingleTickerProviderStateMixin {
int tabIndex = 0;
TabController tabController;
String title = "Home";
#override
void initState() {
super.initState();
tabController = new TabController(length: 3, vsync: this);
}
#override
void dispose() {
tabController.dispose();
super.dispose();
}
#override
Widget build(BuildContext context) {
return DefaultTabController(
length: 3,
child: Scaffold(
appBar: PreferredSize(
preferredSize: Size.fromHeight(kToolbarHeight),
child: Container(
height: 50.0,
child: new TabBar(
indicatorColor: Colors.blue,
unselectedLabelColor: Colors.grey,
labelColor: Colors.blue,
tabs: [
Tab(
text: "Home",
),
Tab(
text: "Mail",
),
Tab(
text: "Profile",
),
],
),
),
),
body: TabBarView(
children: [
MyHomeScreen(),
MailScreen(),
ProfileScreen(),
],
),
),
);
}
}
class MyHomeScreen extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: NestedTabBar()
),
);
}
}
class NestedTabBar extends StatefulWidget {
#override
_NestedTabBarState createState() => _NestedTabBarState();
}
class _NestedTabBarState extends State<NestedTabBar> with TickerProviderStateMixin {
int tabIndex=0;
#override
Widget build(BuildContext context) {
return Scaffold(
body: Container(
color: Colors.white,
child: tabIndex ==0 ?BottomTabBarHome()
:tabIndex == 1? BottomTabBarMail(): BottomTabBarProfile()
),
bottomNavigationBar: BottomNavigationBar(
items: <BottomNavigationBarItem>[
BottomNavigationBarItem(
icon: Icon(Icons.home, color: Colors.grey,),
activeIcon: Icon(Icons.home, color: Colors.blue,),
title: Text('')
),
BottomNavigationBarItem(
icon: Icon(Icons.mail, color: Colors.grey,),
activeIcon: Icon(Icons.mail, color: Colors.blue,),
title: Text('')
),
BottomNavigationBarItem(
icon: Icon(Icons.account_circle, color: Colors.grey,),
activeIcon: Icon(Icons.account_circle, color: Colors.blue,),
title: Text('')
)
],
currentIndex: tabIndex,
selectedItemColor: Colors.blueAccent,
onTap: (int index){
setState(() {
tabIndex = index;
});
},
),
);
}
}
class BottomTabBarHome extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Text("Bottom Tab Bar Home Screen"),
),
);
}
}
class BottomTabBarMail extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Text("Bottom Tab Bar Mail Screen"),
),
);
}
}
class BottomTabBarProfile extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Text("Bottom Tab BarM Profile Screen"),
),
);
}
}
Oh! you got your answer, but i also tried :)
Look:

Related

The method 'TopTapBar' isn't defined for the type '_MyHomePageState'

I am trying to build the bottomNavigationBar with Toptabbar. bottomNavigationBar is working fine but trying to diploy Toptabbar but getting an error of The method 'TopTapBar' isn't defined for the type '_MyHomePageState'. How can I define method from One statefull widget to another stateful widget?
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
const MyApp({super.key});
#override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Navigation Bar',
theme: ThemeData(
primaryColor: Color(0xFFC41A3B),
primaryColorLight: Color(0xFFFBE0E6),
),
home: MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({super.key});
#override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage>
with SingleTickerProviderStateMixin {
String title = 'Tapbar/BottomNav';
late TabController _tabController;
#override
void initState() {
super.initState();
_tabController = TabController(length: 5, vsync: this);
}
#override
void dispose() {
super.dispose();
_tabController.dispose();
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('title'),
centerTitle: true,
elevation: 0.0,
),
body: Center(
child: TabBarView(
controller: _tabController,
physics: NeverScrollableScrollPhysics(),
children: const <Widget>[
TopTapBar(),
Center(
child: Text(
'Home',
style: TextStyle(fontSize: 32.0),
),
),
Center(
child: Text(
'Category',
style: TextStyle(fontSize: 32.0),
),
),
Center(
child: Text(
'Search',
style: TextStyle(fontSize: 32.0),
),
),
Center(
child: Text(
'Cart',
style: TextStyle(fontSize: 32.0),
),
),
Center(
child: Text(
'Profile',
style: TextStyle(fontSize: 32.0),
),
),
],
),
),
bottomNavigationBar: Container(
color: Color(0xFFC41A3B),
child: TabBar(
controller: _tabController,
unselectedLabelColor: Colors.black12,
indicator: UnderlineTabIndicator(),
labelColor: Colors.white,
labelStyle: TextStyle(fontSize: 12.0),
tabs: const [
Tab(
icon: Icon(Icons.home),
text: 'Home',
),
Tab(
icon: Icon(Icons.category),
text: 'Category',
),
Tab(
icon: Icon(Icons.search),
text: 'Search',
),
Tab(
icon: Icon(Icons.shopping_cart),
text: 'Cart',
),
Tab(
icon: Icon(Icons.person),
text: 'Person',
),
],
),
),
);
}
}
class TopTapBAR extends StatefulWidget {
const TopTapBAR({super.key});
#override
State<TopTapBAR> createState() => _TopTapBARState();
}
class _TopTapBARState extends State<TopTapBAR>
with SingleTickerProviderStateMixin {
late TabController _taBcontroller;
#override
void initState() {
super.initState();
_taBcontroller = TabController(length: 3, vsync: this);
}
#override
void dispose() {
super.dispose();
_taBcontroller.dispose();
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: PreferredSize(
preferredSize: Size.fromHeight(kToolbarHeight),
child: Container(
color: Color(0xFFC41A3B),
child: TabBar(
controller: _taBcontroller,
indicator: UnderlineTabIndicator(),
labelColor: Colors.white,
labelStyle: TextStyle(fontSize: 12.0),
indicatorWeight: 5.0,
tabs: const [
Tab(
text: 'Paid',
),
Tab(
text: 'Unpaid',
),
Tab(
text: 'Level',
),
],
),
),
),
body: TabBarView(
controller: _taBcontroller,
physics: NeverScrollableScrollPhysics(),
children:const[
Center(child: Text('Paid',style: TextStyle(fontSize: 32.0),)),
Center(child: Text('Unpaid',style: TextStyle(fontSize: 32.0),)),
Center(child: Text('Level',style: TextStyle(fontSize: 32.0),)),
],
),
);
}
}
This is type issue as #kasia described on comment.
Change it like
class TopTapBar extends StatefulWidget {
const TopTapBar({super.key});
#override
State<TopTapBar> createState() => _TopTapBarState();
}
class _TopTapBarState extends State<TopTapBar>
with SingleTickerProviderStateMixin {

How to keep the TextField value when changing the tab(multiple)?

I don't know why that the TextField input will missing when changing tab.
How to keep the data when changethe tab?
I don't know why it will dismiss. Did I need add the controller for TextField?
For example, I input in "one"
Then go to "two" and input
Back to "one", the textfield data will missing.
same think also occur in bottom tab
Sources code:
import "package:flutter/material.dart";
class MultiTabScreen extends StatefulWidget {
#override
_MultiTabScreen createState() => _MultiTabScreen();
}
class _MultiTabScreen extends State<MultiTabScreen>
with SingleTickerProviderStateMixin {
TabController tabController;
String title = "Home";
#override
void initState() {
super.initState();
tabController = new TabController(length: 3, vsync: this);
}
#override
void dispose() {
tabController.dispose();
super.dispose();
}
#override
Widget build(BuildContext context) {
// TODO: implement build
return MaterialApp(
theme: ThemeData(
primarySwatch: Colors.purple,
brightness: Brightness.light,
accentColor: Colors.red),
darkTheme: ThemeData(
brightness: Brightness.dark,
),
home: new Scaffold(
appBar: AppBar(
title: Text(title),
centerTitle: true,
),
body: TabBarView(
children: <Widget>[
FirstTab(),
MyBody("Page Two"),
MyBody("Page Three")
],
// if you want yo disable swiping in tab the use below code
// physics: NeverScrollableScrollPhysics(),
controller: tabController,
),
bottomNavigationBar: Material(
color: Colors.purple,
child: TabBar(
onTap: (indedx) {
if (indedx == 0) {
setState(() {
title = "Home";
});
} else if (indedx == 1) {
setState(() {
title = "Tab Two";
});
} else if (indedx == 2) {
setState(() {
title = "Tab Three";
});
}
},
indicatorColor: Colors.blue,
unselectedLabelColor: Colors.grey,
tabs: <Widget>[
Tab(
icon: Icon(Icons.favorite_border),
text: "ONE",
),
Tab(
icon: Icon(Icons.favorite),
text: "TWO",
),
Tab(
icon: Icon(Icons.add_box),
text: "THREE",
),
],
controller: tabController,
),
),
));
}
}
class FirstTab extends StatefulWidget {
#override
FirstTabState createState() => FirstTabState();
}
class FirstTabState extends State<FirstTab>
with SingleTickerProviderStateMixin {
TabController tabController;
#override
void initState() {
super.initState();
tabController = new TabController(length: 3, vsync: this);
}
#override
void dispose() {
tabController.dispose();
super.dispose();
}
#override
Widget build(BuildContext context) {
// TODO: implement build
return DefaultTabController(
length: 3,
child: Scaffold(
appBar: PreferredSize(
preferredSize: Size.fromHeight(kToolbarHeight),
child: Container(
height: 50.0,
child: new TabBar(
indicatorColor: Colors.blue,
unselectedLabelColor: Colors.grey,
labelColor: Colors.blue,
tabs: [
Tab(
text: "ONE",
),
Tab(
text: "TWO",
),
Tab(
text: "THREE",
),
],
),
),
),
body: TabBarView(
children: [
Container(
width: 300.0,
child: TextField(
decoration: InputDecoration(
border: OutlineInputBorder(),
labelText: 'Number',
),
),
),
Container(
width: 300.0,
child: TextField(
decoration: InputDecoration(
border: OutlineInputBorder(),
labelText: 'Number',
),
),
),
Container(
width: 300.0,
child: TextField(
decoration: InputDecoration(
border: OutlineInputBorder(),
labelText: 'Number',
),
),
),
],
),
),
);
}
}
class MyBody extends StatelessWidget {
final String title;
MyBody(this.title);
final mySnackBar = SnackBar(
content: Text(
"Hello There!",
style: TextStyle(color: Colors.white),
),
duration: Duration(seconds: 3),
backgroundColor: Colors.blue,
);
#override
Widget build(BuildContext context) {
// TODO: implement build
return Container(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Container(
width: 300.0,
child: TextField(
decoration: InputDecoration(
border: OutlineInputBorder(),
labelText: 'Number',
),
),
),
],
),
);
}
}
From your source code, I can see you are not storing your value.
you should store it in some variables.
there are two types of them.
String value = "";
TextField(
onChanged: (text) {
value = text;
},
)
or you can use a controller too.
TextEditingController controller = TextEditingController();
TextField(
controller: controller,
)
If doesn't work try with global Scope that means declare variable outside of Class...

Flutter how to create clickable tabs

How to create basic design like from sketch from image. First container with list of tabs is static, and containers above it is dynamic, and contain text - Text for tab 1 if tab 1 is clicked, or Text for tab 2 if tab 2 is clicked. Also text for Tab1 or Tab2 must be underline if we click on it.
Something like this:
Using a GestureDetector widget to tell when a user taps on the tabs and then updating the state with setState is maybe the most simple way of doing this.
Here is a very basic example of using a stateful widget and setState to update the page. You can approach this problem with any state management strategy, though.
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: Scaffold(body: MyHomePage()),
);
}
}
class MyHomePage extends StatefulWidget {
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
String selectedTab;
static const String TAB_1 = 'Tab 1';
static const String TAB_2 = 'Tab 2';
#override
Widget build(BuildContext context) {
return Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Expanded(
flex: 1,
child: Row(
crossAxisAlignment: CrossAxisAlignment.end,
children: [
GestureDetector(
onTap: () {
setState(() => selectedTab = TAB_1);
},
child: Container(
padding: const EdgeInsets.all(12.0),
child: Text(TAB_1),
decoration: selectedTab == TAB_1
? BoxDecoration(border: Border(bottom: BorderSide()))
: null,
),
),
GestureDetector(
onTap: () {
setState(() => selectedTab = TAB_2);
},
child: Container(
padding: const EdgeInsets.all(12.0),
child: Text(TAB_2),
decoration: selectedTab == TAB_2
? BoxDecoration(border: Border(bottom: BorderSide()))
: null,
),
)
],
),
),
Container(height: 20.0),
Expanded(
flex: 2,
child: Container(
decoration: BoxDecoration(
border: Border.all(width: 5),
borderRadius: BorderRadius.circular(12.0)),
child: Center(child: Text(textForTab(selectedTab))),
),
)
],
);
}
String textForTab(String tabId) {
switch (tabId) {
case TAB_1:
return 'Text for Tab 1';
case TAB_2:
return 'Text for Tab 2';
default:
return 'Select Tab';
}
}
}
You can do it using TabBar widget.
class CustomTabBar extends StatefulWidget {
#override
_CustomTabBarState createState() => _CustomTabBarState();
}
class _CustomTabBarState extends State<CustomTabBar>
with SingleTickerProviderStateMixin {
TabController _tabController;
#override
void initState() {
_tabController = TabController(length: 2, vsync: this);
super.initState();
}
#override
void dispose() {
super.dispose();
_tabController.dispose();
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(
'Tab Demo',
),
),
body:
Column(
children: [
Container(
height: 45,
child: TabBar(
controller: _tabController,
indicator: BoxDecoration(
border: Border(bottom: BorderSide(color: Colors.blue,width: 2,style:
BorderStyle.solid)),
),
labelColor: Colors.blue,
unselectedLabelColor: Colors.black,
tabs: [
// first tab
Tab(
text: 'Home',
),
// second tab
Tab(
text: 'Profile',
),
],
),
),
// tab bar view
Expanded(
child: TabBarView(
controller: _tabController,
children: [
// first tab widget
Center(
child: Text(
'Home',
style: TextStyle(
fontSize: 26,
fontWeight: FontWeight.bold,
),
),
),
// Second tab widget
Center(
child: Text(
'Profile',
style: TextStyle(
fontSize: 26,
fontWeight: FontWeight.bold,
),
),
),
],
),
),
],
),
);
}
}
I'm not sure I understand you completely.
But if you want to implement a TabBar, you can use flutter TabBar() documented here:
https://flutter.dev/docs/cookbook/design/tabs
Or there is a package you can use:
https://pub.dev/packages/tabbar

Back button leads to a very first page

I use a DefaultTabController tabbar which looks like this
class MainTabs extends StatelessWidget {
#override
Widget build(BuildContext context) {
return DefaultTabController(
length: 3,
child: Scaffold(
appBar: MyAppbar(),
body: TabBarView(
children: [
CardContentPage(title: 'Tab1'),
DeviceContentPage(title: 'Tab2'),
SettingsPage(title: 'Tab2'),
],
),
),
);
}
}
But with this design the back button always leads to a very first page of the application.
How can I set up it so that back button works as expected with DefaultTabController?
Using a DefaultTabController you can just prevent the user from return, using the WillPopScope:
DefaultTabController(
initialIndex: 0,
length: 3,
child: WillPopScope(
onWillPop: () async {
return false;
},
child: Scaffold(
appBar: AppBar(
bottom: TabBar(tabs: [
Tab(text: 'First',),
Tab(text: 'Second',),
Tab(text: 'Third',),
]),
),
body: TabBarView(
children: [
Container(color: Colors.red,),
Container(color: Colors.yellow,),
Container(color: Colors.green,),
],
),
),
),
);
But with a TabController you can set the route to the previous page:
class TabPage extends StatefulWidget {
#override
_TabPageState createState() => _TabPageState();
}
class _TabPageState extends State<TabPage> with SingleTickerProviderStateMixin {
TabController tabController;
#override
void initState() {
tabController = TabController(length: 3, vsync: this);
super.initState();
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
bottom: TabBar(
controller: tabController,
tabs: [
Tab(
text: 'First',
),
Tab(
text: 'Second',
),
Tab(
text: 'Third',
),
],
),
),
body: TabBarView(
controller: tabController,
children: [
Container(
color: Colors.red,
),
WillPopScope(
onWillPop: () async {
tabController.animateTo(0, duration: Duration(milliseconds: 500),);
return false;
},
child: Container(
color: Colors.yellow,
),
),
WillPopScope(
onWillPop: ()async {
tabController.animateTo(1, duration: Duration(milliseconds: 500),);
return false;
},
child: Container(
color: Colors.green,
),
),
],
),
);
}
}

how to make tabview inside another tabview in flutter?

I tried to create nested tabs bar views in the following way, by returning a column containing another tab view from the outer tab view, however it just shows a blank screen instead of the second tab view. How can I fix this?
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: DefaultTabController(length: 2, child: MyHomePage(title: '')),
);
}
}
class MyHomePage extends StatelessWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
#override
Widget build(BuildContext context){
final view = LayoutBuilder(builder: (context, constraints){
//created a widget here with content
});
return Scaffold(
appBar: AppBar(
title: Text('Tab bar view'), bottom: TabBar(
tabs: [
Tab(icon: Icon(Icons.directions_car)),
Tab(icon: Icon(Icons.directions_transit)),
]),
),
body: TabBarView(children: [DefaultTabController(length: 2, child: Column(
children: <Widget>[TabBar(tabs: [Tab(text: 'Home'),Tab(text: 'News')
, Container(child: TabBarView(
children: <Widget>[ view, Icon(Icons.access_alarms)],
))])]
) ), Icon(Icons.directions_car)]));
}
}
Best Way to do it just like in Google Play store.
import 'package:flutter/material.dart';
class Locationstat extends StatefulWidget {
#override
_LocationstatState createState() => _LocationstatState();
}
class _LocationstatState extends State<Locationstat>
with SingleTickerProviderStateMixin {
late TabController _tabController;
#override
void initState() {
super.initState();
_tabController = new TabController(length: 2, vsync: this);
}
#override
void dispose() {
super.dispose();
_tabController.dispose();
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: Colors.white,
elevation: 0,
title: Text('Statistics'),
bottom: TabBar(
controller: _tabController,
indicatorColor: Colors.orange,
labelColor: Colors.orange,
unselectedLabelColor: Colors.black54,
tabs: <Widget>[
Tab(
text:('Pokhara Lekhnath'),
),
Tab(
text:('Outside Pokhara-Lekhnath'),
),
]),
),
body: TabBarView(
children: <Widget>[
NestedTabBar(),
NestedTabBar(),
],
controller: _tabController,
),
);
}
}
class NestedTabBar extends StatefulWidget {
#override
_NestedTabBarState createState() => _NestedTabBarState();
}
class _NestedTabBarState extends State<NestedTabBar>
with TickerProviderStateMixin {
late TabController _nestedTabController;
#override
void initState() {
super.initState();
_nestedTabController = new TabController(length: 2, vsync: this);
}
#override
void dispose() {
super.dispose();
_nestedTabController.dispose();
}
#override
Widget build(BuildContext context) {
double screenHeight = MediaQuery.of(context).size.height;
return Column(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: <Widget>[
TabBar(
controller: _nestedTabController,
indicatorColor: Colors.orange,
labelColor: Colors.orange,
unselectedLabelColor: Colors.black54,
isScrollable: true,
tabs: <Widget>[
Tab(
text: "Inside Pokhara",
),
Tab(
text: "Outside Pokhara",
),
],
),
Container(
height: screenHeight * 0.70,
margin: EdgeInsets.only(left: 16.0, right: 16.0),
child: TabBarView(
controller: _nestedTabController,
children: <Widget>[
Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(8.0),
color: Colors.blueGrey[300],
),
),
Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(8.0),
color: Colors.blueGrey[300],
),
),
],
),
)
],
);
}
}
import 'package:flutter/material.dart';
class Locationstat extends StatefulWidget {
#override
_LocationstatState createState() => _LocationstatState();
}
class _LocationstatState extends State<Locationstat>
with SingleTickerProviderStateMixin {
TabController _tabController;
#override
void initState() {
super.initState();
_tabController = new TabController(length: 2, vsync: this);
}
#override
void dispose() {
super.dispose();
_tabController.dispose();
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: Colors.white,
elevation: 0,
title: Text('Statistics'),
bottom: TabBar(
controller: _tabController,
indicatorColor: Colors.orange,
labelColor: Colors.orange,
unselectedLabelColor: Colors.black54,
tabs: <Widget>[
Tab(
text:('Pokhara Lekhnath'),
),
Tab(
text:('Outside Pokhara-Lekhnath'),
),
]),
),
body: TabBarView(
children: <Widget>[
NestedTabBar(),
NestedTabBar(),
],
controller: _tabController,
),
);
}
}
class NestedTabBar extends StatefulWidget {
#override
_NestedTabBarState createState() => _NestedTabBarState();
}
class _NestedTabBarState extends State<NestedTabBar>
with TickerProviderStateMixin {
TabController _nestedTabController;
#override
void initState() {
super.initState();
_nestedTabController = new TabController(length: 2, vsync: this);
}
#override
void dispose() {
super.dispose();
_nestedTabController.dispose();
}
#override
Widget build(BuildContext context) {
double screenHeight = MediaQuery.of(context).size.height;
return Column(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: <Widget>[
TabBar(
controller: _nestedTabController,
indicatorColor: Colors.orange,
labelColor: Colors.orange,
unselectedLabelColor: Colors.black54,
isScrollable: true,
tabs: <Widget>[
Tab(
text: "Inside Pokhara",
),
Tab(
text: "Outside Pokhara",
),
],
),
Container(
height: screenHeight * 0.70,
margin: EdgeInsets.only(left: 16.0, right: 16.0),
child: TabBarView(
controller: _nestedTabController,
children: <Widget>[
Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(8.0),
color: Colors.blueGrey[300],
),
),
Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(8.0),
color: Colors.blueGrey[300],
),
),
],
),
)
],
);
}
}
you can do that by adding BottomNavigationBar to the Scaffold and route to a widget that contains the TabBar
Check this, https://github.com/whatsupcoders/Flutter-Nested-Tabs
It has code, which has a UI replication of the Google Play Store.
Here' the image
Here's the tutorial for it: https://www.youtube.com/watch?v=bSywfMPuwaw
Cheers!