No TabController for TabBar - flutter

I'm trying to add a tabBar to my app, but I'm having some issues getting it to build. I've followed the documentation and added a tabController, but I'm getting an error saying I don't have one. My code is below.
class _MyAppState extends State<MyApp> with TickerProviderStateMixin {
TabController _controller;
final List<Tab> topTabs = <Tab>[
new Tab(text: 'Profile'),
new Tab(text: 'Match'),
new Tab(text: 'Chat'),
];
#override
void initState() {
super.initState();
_controller = TabController(vsync: this, length: 3);
}
#override
void dispose() {
_controller.dispose();
super.dispose();
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('MyApp'),
bottom: TabBar(
controller: _controller,
tabs: topTabs,
),
),
body: TabBarView(
controller: _controller,
children: [
new Container(
color: Colors.lightBlueAccent,
child: Center(child: Text('Profile', style: TextStyle(color: Colors.white),),),
),
new Container(
color: Colors.purpleAccent,
child: Center(child: Text('Match', style: TextStyle(color: Colors.white),),),
),
new Container(
color: Colors.lightGreenAccent,
child: Center(child: Text('Chat', style: TextStyle(color: Colors.white),),),
)
]),
);
}
}
The exact error is flutter: ══╡ EXCEPTION CAUGHT BY WIDGETS LIBRARY ╞═══════════════════════════════════════════════════════════
flutter: The following assertion was thrown building MediaQuery(MediaQueryData(size: Size(375.0, 667.0),
flutter: devicePixelRatio: 2.0, textScaleFactor: 1.0, platformBrightness: Brightness.light, padding:
flutter: EdgeInsets.zero, viewPadding: EdgeInsets.zero, viewInsets: EdgeInsets.zero, physicalDepth:
flutter: 1.7976931348623157e+308, alwaysUse24HourFormat: false, accessibleNavigation: false, highContrast:
flutter: false, disableAnimations: false, invertColors: false, boldText: false)):
flutter: No TabController for TabBar.
flutter: When creating a TabBar, you must either provide an explicit TabController using the "controller"
flutter: property, or you must ensure that there is a DefaultTabController above the TabBar.
flutter: In this case, there was neither an explicit controller nor a default controller.

I could run it without a problem, did you overwrote MyApp example when creating your project that has the MaterialApp with your code or something before the main?
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
home: MyAppState()
);
}
}
class MyAppState extends StatefulWidget{
#override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyAppState> with TickerProviderStateMixin {
TabController _controller;
final List<Tab> topTabs = <Tab>[
new Tab(text: 'Profile'),
new Tab(text: 'Match'),
new Tab(text: 'Chat'),
];
#override
void initState() {
super.initState();
_controller = TabController(vsync: this, length: 3);
}
#override
void dispose() {
_controller.dispose();
super.dispose();
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('MyApp'),
bottom: TabBar(
controller: _controller,
tabs: topTabs,
),
),
body: TabBarView(
controller: _controller,
children: [
new Container(
color: Colors.lightBlueAccent,
child: Center(child: Text('Profile', style: TextStyle(color: Colors.white),),),
),
new Container(
color: Colors.purpleAccent,
child: Center(child: Text('Match', style: TextStyle(color: Colors.white),),),
),
new Container(
color: Colors.lightGreenAccent,
child: Center(child: Text('Chat', style: TextStyle(color: Colors.white),),),
)
]),
);
}
}

Related

Handle back button in Tabbar flutter

I have a TabBarthat show total of 16 catgories that shows dynamically,
Usecase:when i click on category any cateogry let's say i click on category 5 then if i press back button in phone i need to go to the category 1,as default i can show category 1 also if i press backbutton 2 time i need to close the app too
but i need to show category 1 when i press back button how do i do that, i have tried with willpopScope but nothing happens,This is what i tried so far
WillPopScope(
onWillPop: _onWillPop,
child: category_list.length != 0
? DefaultTabController(
length: category_list.length,
initialIndex: 1,
child: Column(
children: <Widget>[
Column(
children: [
Container(
constraints: BoxConstraints.expand(height: 40),
child: TabBar(
controller: _tabController,
isScrollable: true,
indicatorColor: Color(0xff00ADEE),
labelColor: Color(0xff00ADEE),
unselectedLabelColor: Colors.black,
tabs: getTab(),
),
),
],
),
Expanded(
child: Container(
child: TabBarView(
controller: _tabController,
children: createDynamicslugWIdget()),
),
)
],
),
)
: Center(
child: CircularProgressIndicator(),
),
)
Tried to return index 1
Future<bool> _onWillPop() async {
return _tabController.index==1;
}
You can copy paste run full code below
I use official example to simulate this case
You can set _tabController.index
code snippet
Future<bool> _onWillPop() async {
print("on will pop");
if (_tabController.index == 0) {
await SystemNavigator.pop();
}
Future.delayed(Duration(milliseconds: 200), () {
print("set index");
_tabController.index = 0;
});
print("return");
return _tabController.index == 0;
}
working demo
full code
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
class MyTabbedPage extends StatefulWidget {
const MyTabbedPage({Key key}) : super(key: key);
#override
_MyTabbedPageState createState() => _MyTabbedPageState();
}
class _MyTabbedPageState extends State<MyTabbedPage>
with SingleTickerProviderStateMixin {
final List<Tab> myTabs = <Tab>[
Tab(text: '0'),
Tab(text: '1'),
Tab(text: '2'),
Tab(text: '3'),
Tab(text: '4'),
];
TabController _tabController;
#override
void initState() {
super.initState();
_tabController = TabController(vsync: this, length: myTabs.length);
}
#override
void dispose() {
_tabController.dispose();
super.dispose();
}
Future<bool> _onWillPop() async {
print("on will pop");
if (_tabController.index == 0) {
await SystemNavigator.pop();
}
Future.delayed(Duration(milliseconds: 200), () {
print("set index");
_tabController.index = 0;
});
print("return");
return _tabController.index == 0;
}
#override
Widget build(BuildContext context) {
return WillPopScope(
onWillPop: _onWillPop,
child: Scaffold(
appBar: AppBar(
bottom: TabBar(
controller: _tabController,
tabs: myTabs,
),
),
body: TabBarView(
controller: _tabController,
children: myTabs.map((Tab tab) {
final String label = tab.text.toLowerCase();
return Center(
child: Text(
'This is the $label tab',
style: const TextStyle(fontSize: 36),
),
);
}).toList(),
),
),
);
}
}
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: MyTabbedPage(),
);
}
}

flutter, RenderBox was not laid out: RenderRepaintBoundary#4de33 relayoutBoundary=up14 NEEDS-PAINT

I use tabBar,
I want to change appBar title when a tab is selected, but I get a error.
code that I get error.
Scaffold(
appBar: AppBar(
leading: IconButton(
icon: Icon(Icons.clear, color: Colors.black),
onPressed: () {
Navigator.pop(context);
},
),
title: TabBarView(
children: [Text("Album"), Text("사진"), Text("동영상")],
),
backgroundColor: Colors.white,
),
bottomNavigationBar: TabBar(
tabs: [
Tab(text: "앨범"),
Tab(text: "사진"),
Tab(text: "동영상"),
],
labelColor: Colors.black,
indicatorColor: Colors.black,
unselectedLabelColor: Colors.black26,
),
),
If I get rid of appBar title, I don't get error.
How to solve this problem?
You can add TabController and add a listener so that whenever you are switching the Tab, the setState() kicks in and the appBar title change.
class MyHomePage extends StatefulWidget {
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> with TickerProviderStateMixin {
TabController _controller;
final List<Tab> _tab = [new Tab(text: "First",), Tab(text: "Second",), Tab(text: "Third",)];
var _currentTab;
#override
void initState() {
// TODO: implement initState
super.initState();
_controller = new TabController(length: _tab.length, vsync: this);
_currentTab = _tab[0];
_controller.addListener(_selectedTab);
}
void _selectedTab() {
setState(() {
_currentTab = _tab[_controller.index];
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: new Text(_currentTab.text),
),
bottomNavigationBar: TabBar(controller: _controller,tabs: _tab),
);
}
}

On button click navigate to a tab screen

I am using a tab controller in flutter, but how do i able to navigate to a certain tab screen with a button click. I put my tab controller in my main screen then 3 different screens. Below is my example codes.
Main Screen (with tab controller)
class HomePage extends StatefulWidget {
#override
_HomePageState createState() => new _HomePageState();
}
class _HomePageState extends State<HomePage>
with SingleTickerProviderStateMixin {
int _currentIndex = 0;
TabController _tabController;
final List<Widget> _children = [
firstscreen.FirstScreen(),
secondscreen.SecondScreen(),
thirdscreen.ThirdScreen()
];
List<Widget> _tabs = <Widget>[
Tab(icon: Icon(Icons.home), text: 'Home'),
Tab(icon: Icon(Icons.history), text: 'History'),
Tab(icon: Icon(Icons.account_circle), text: 'Profile'),
];
#override
void initState() {
super.initState();
_tabController = TabController(length: _tabs.length, vsync: this);
}
#override
void dispose() {
_tabController.dispose();
super.dispose();
}
#override
Widget build(BuildContext context) {
return WillPopScope(
onWillPop: _onWillPop,
child: Scaffold(
appBar: AppBar(
title: Text("My Title"),
actions: <Widget>[
IconButton(
icon: Icon(Icons.account_balance_wallet),
onPressed: () {
Navigator.push(context,
MaterialPageRoute(builder: (context) => Data Screen()));
},
),
],
bottom: TabBar(
controller: _tabController,
tabs: _tabs,
),
),
body: TabBarView(
controller: _tabController,
children: _children,
),
),
);
}
void onTabTapped(int index) {
setState(() {
_currentIndex = index;
});
}
First Screen
class FirstScreen extends StatefulWidget {
FirstScreen({Key key}) : super(key: key);
#override
FirstScreenState createState() {
return new FirstScreenState();
}
}
class FirstScreenState extends State<FirstScreen>
with AutomaticKeepAliveClientMixin<FirstScreen> {
Widget get historyCard {
return Container(
height: 280,
width: MediaQuery.of(context).size.width / 1,
padding: EdgeInsets.only(top: 10.0, left: 20.0, right: 20.0),
child: Card(
elevation: 4.0,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10.0),
),
child: Stack(
children: <Widget>[
ClipPath(
clipper: ShapeBorderClipper(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10.0),
),
),
),
Stack(alignment: Alignment.center, children: <Widget>[
Positioned(
top: 10,
left: 10,
child: Text("RECENT ACTIVITY",
style: TextStyle(
fontSize: 14.0,
)),
),
Positioned(
top: 0,
right: 0,
child: FlatButton(
child: Text('MORE >'),
onPressed: () => {},
textColor: Colors.blueAccent, // JUMP TO SECOND TAB or ANY
//OTHER TAB
),
),
]),
],
),
),
);
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: Column(children: [
historyCard,
]),
);
}
}
So right now i'm not sure how do i able to navigate to any tab with button click, because i place my tab bar in MainScreen.dartor must i change the FirstPage code into the MainScreen.dart, then only can click and navigate?
You can set index in TabController to change current tab as below:
In below example, one button is in TabBarView screen in "MyFirstTab", from that button press we call the changeMyTab() of parent class which is "StateKeeper".
import 'package:flutter/material.dart';
class MyTabController extends StatefulWidget {
createState() {
return StateKeeper();
}
}
class StateKeeper extends State<MyTabController> with SingleTickerProviderStateMixin {
TabController _tabController;
final List<Tab> myTabs = <Tab>[
new Tab(icon: Icon(Icons.directions_car),),
new Tab(icon: Icon(Icons.directions_bike),),
new Tab(icon: Icon(Icons.directions_boat),),
new Tab(icon: Icon(Icons.directions_railway),),
];
#override
void initState() {
// TODO: implement initState
super.initState();
_tabController = new TabController(vsync: this, length: myTabs.length);
}
changeMyTab(){
setState(() {
_tabController.index = 2;
});
}
#override
Widget build(BuildContext context) {
return MaterialApp(
home: DefaultTabController(
length: 4,
child: Scaffold(
appBar: AppBar(
bottom: TabBar(tabs: myTabs, controller: _tabController,),
title: Text('Tabs Demo'),
),
body: TabBarView(controller: _tabController, children: [
MyFirstTab(onTabChangeCallback: () => {
changeMyTab()
},),
Icon(Icons.directions_bike),
Icon(Icons.directions_boat),
Icon(Icons.directions_railway),
]),
),
),
);
}
}
class MyFirstTab extends StatefulWidget {
const MyFirstTab({this.onTabChangeCallback});
final TabChangeCallback onTabChangeCallback;
createState() {
return MyFirstTabStateKeeper(onTabChangeCallback);
}
}
class MyFirstTabStateKeeper extends State<MyFirstTab> {
TabChangeCallback onTabChangeCallback;
MyFirstTabStateKeeper(TabChangeCallback onTabChangeCallback){
this.onTabChangeCallback = onTabChangeCallback;
}
#override
void initState() {
// TODO: implement initState
super.initState();
}
#override
Widget build(BuildContext context) {
return Column(
children: <Widget>[
RaisedButton(
child: Text('Change Tab'),
onPressed: onTabChangeCallback,
),
],
);
}
}
typedef TabChangeCallback = void Function();

DefaultTabBarController with flutter

I am using defaulttabbarcontroller
Here is the code
tab.dart
void main() => runApp(TabBar1());
final key = new GlobalKey<TabBar1State>();
class TabBar1 extends StatefulWidget {
TabBar1({Key key}) : super(key: key);
#override
State<StatefulWidget> createState() => TabBar1State();
}
class TabBar1State extends State<TabBar1> with SingleTickerProviderStateMixin {
TabController tabController;
#override
void initState() {
super.initState();
tabController = TabController(vsync: this, length: 2);
}
#override
Widget build(BuildContext context) {
return new MaterialApp(
debugShowCheckedModeBanner: false,
home: DefaultTabController(
length: 2,
child: Scaffold(
appBar: PreferredSize(
child: AppBar(
backgroundColor: Colors.greenAccent,
bottom: TabBar(
controller: tabController,
tabs: [
Tab(
child: Text("Login"),
),
Tab(
child: Text("Sign Up"),
),
],
indicatorColor: Colors.black,
),
flexibleSpace: Container(
decoration: BoxDecoration(
gradient: LinearGradient(
colors: [
Colors.red,
Colors.orange,
],
),
),
),
),
preferredSize: Size.fromHeight(200.0),
),
body: TabBarView(
controller: tabController,
children: [
LoginApp(),
SignUpApp(),
],
),
),
),
);
}
}
and here is my snippet where I want to call my SignUp() tab from login page
LoginApp() page code snippet
Padding(
padding: EdgeInsets.only(top: 30, bottom: 30),
child: new RichText(
text: TextSpan(
text: "Don't have an account? ",
style: DefaultTextStyle.of(context).style,
children: <TextSpan>[
new TextSpan(
text: 'Sign Up',
style: new TextStyle(
fontWeight: FontWeight.bold),
recognizer: TapGestureRecognizer()
..onTap = () {
key.currentState.tabController.animateTo(
(key.currentState.tabController
.index +
1) %
2);
}),
]),
))
but I am getting following error
The following NoSuchMethodError was thrown while handling a gesture:
I/flutter (17770): The getter 'tabController' was called on null.
I/flutter (17770): Receiver: null
I/flutter (17770): Tried calling: tabController
I/flutter (17770):
How to do the same and what I have done wrong?
Please help
Obviously the tabcontroller isn't getting anything. The following code is probably what you're looking for
import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
void main() => runApp(new MyApp());
class MyApp extends StatefulWidget {
static final _myTabbedPageKey = new GlobalKey<_MyTabbedPageState>();
#override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
#override
Widget build(BuildContext context) {
return new MaterialApp(
title: 'Flutter Demo',
home: new MyTabbedPage(
key: MyApp._myTabbedPageKey,
),
);
}
}
class MyTabbedPage extends StatefulWidget {
const MyTabbedPage({Key key}) : super(key: key);
#override
_MyTabbedPageState createState() => new _MyTabbedPageState();
}
class _MyTabbedPageState extends State<MyTabbedPage> with SingleTickerProviderStateMixin {
final List<Tab> myTabs = <Tab>[
new Tab(text: 'LEFT'),
new Tab(text: 'RIGHT'),
];
TabController _tabController;
#override
void initState() {
super.initState();
_tabController = new TabController(vsync: this, length: myTabs.length);
}
#override
void dispose() {
_tabController.dispose();
super.dispose();
}
#override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: new Text("Tab demo"),
bottom: new TabBar(
controller: _tabController,
tabs: myTabs,
),
),
body: new TabBarView(
controller: _tabController,
children: [
LoginApp(),
SignUpApp(),
],
),
);
}
}
class LoginApp extends StatefulWidget {
#override
_LoginAppState createState() => _LoginAppState();
}
class _LoginAppState extends State<LoginApp> {
#override
Widget build(BuildContext context) {
return Padding(
padding: EdgeInsets.only(top: 30, bottom: 30),
child: new RichText(
text: TextSpan(
text: "Don't have an account? ",
style: DefaultTextStyle.of(context).style,
children: <TextSpan>[
new TextSpan(
text: 'Sign Up',
style: new TextStyle(
fontWeight: FontWeight.bold),
recognizer: TapGestureRecognizer()
..onTap = () =>
MyApp._myTabbedPageKey.currentState._tabController.animateTo((MyApp._myTabbedPageKey.currentState._tabController.index + 1) % 2),
),
]),
));
}
}
class SignUpApp extends StatefulWidget {
#override
_SignUpAppState createState() => _SignUpAppState();
}
class _SignUpAppState extends State<SignUpApp> {
#override
Widget build(BuildContext context) {
return Text('godbye');
}
}
Here is the answer to my own question
Reference link
tab.dart
void main() => runApp(TabBar1());
//I took stateless widget
class TabBar1 extends StatelessWidget {
static final myTabbedPageKey = new GlobalKey<_TabLoginSignUpState>();
#override
Widget build(BuildContext context) {
return new MaterialApp(
debugShowCheckedModeBanner: false,
//called my stateful widget
home: TabLoginSignUp(
key: TabBar1.myTabbedPageKey,
));
}
}
class TabLoginSignUp extends StatefulWidget {
TabLoginSignUp({Key key}) : super(key: key);
#override
_TabLoginSignUpState createState() => _TabLoginSignUpState();
}
class _TabLoginSignUpState extends State<TabLoginSignUp>
with SingleTickerProviderStateMixin {
TabController tabController;
#override
void initState() {
super.initState();
tabController = TabController(vsync: this, length: 2);
}
#override
Widget build(BuildContext context) {
return DefaultTabController(
length: 2,
child: Scaffold(
appBar: PreferredSize(
child: AppBar(
backgroundColor: Colors.greenAccent,
bottom: TabBar(
controller: tabController,
tabs: [
Tab(
child: Text("Login"),
),
Tab(
child: Text("Sign Up"),
),
],
indicatorColor: Colors.black,
),
flexibleSpace: Container(
decoration: BoxDecoration(
gradient: LinearGradient(
colors: [
Colors.red,
Colors.orange,
],
),
),
),
),
preferredSize: Size.fromHeight(200.0),
),
body: TabBarView(
controller: tabController,
children: [
LoginApp(),
SignUpApp(),
],
),
),
);
}
}
updated snippet in LoginApp()
Padding(
padding: EdgeInsets.only(top: 30, bottom: 30),
child: new RichText(
text: TextSpan(
text: "Don't have an account? ",
style: DefaultTextStyle.of(context).style,
children: <TextSpan>[
new TextSpan(
text: 'Sign Up',
style: new TextStyle(
fontWeight: FontWeight.bold),
recognizer: TapGestureRecognizer()
..onTap = () {
//called like this on click TabBar1.myTabbedPageKey.currentState.tabController
.animateTo((TabBar1.myTabbedPageKey.currentState
.tabController.index +
1) %
2);
}),
]),
))

Disable TabView animation on Tab click event?

How can I disable TabView animation when Tab in TabBar clicked ?
I added
physics: NeverScrollableScrollPhysics()
for TabView but that doesn't apply for TabBar.
I'm using DefaultTabController.
Based on a very good answer on github about this issue, which achieves something similar to what your looking for (but with a bottomNavigationBar) here I share with you another workaround. It consists of combining a DefaultTabController with a PageView, a PageController and a simple index. Try this out.
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Tabs with no animation',
theme: ThemeData.dark(),
home: HomeScreen(),
);
}
}
class HomeScreen extends StatefulWidget {
#override
_HomeScreenState createState() => _HomeScreenState();
}
class _HomeScreenState extends State<HomeScreen> {
PageController _pageController;
final int currentTab = 0;
#override
void initState() {
// TODO: implement initState
_pageController = PageController(initialPage: currentTab);
super.initState();
}
final List<Tab> myTabs = <Tab>[
Tab(text: 'One'),
Tab(
text: 'Two',
),
];
var tabs = [
TabOne(),
TabTwo(),
];
#override
Widget build(BuildContext context) {
var pageView = PageView(
controller: _pageController,
physics: NeverScrollableScrollPhysics(),
children: tabs,
);
return DefaultTabController(
length: myTabs.length,
child: Scaffold(
extendBodyBehindAppBar: true,
appBar: AppBar(
backgroundColor: Colors.transparent,
elevation: 0.0,
automaticallyImplyLeading: false,
title: Center(
child: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(30),
color: Colors.grey.shade800,
),
width: 200,
height: 50,
child: TabBar(
onTap: (index) {
_pageController.jumpToPage(index);
},
unselectedLabelColor: Colors.white,
indicator: BoxDecoration(
borderRadius: BorderRadius.circular(30),
color: Colors.black),
tabs: myTabs,
),
),
),
),
body: pageView),
);
}
}
class TabOne extends StatelessWidget {
const TabOne({Key key}) : super(key: key);
#override
Widget build(BuildContext context) {
return Container(
child: Center(child: Text('Tab one')),
);
}
}
class TabTwo extends StatelessWidget {
const TabTwo({Key key}) : super(key: key);
#override
Widget build(BuildContext context) {
return Container(
child: Center(child: Text('Tab two')),
);
}
}
Doing so, you have a something identical to a TabBarView but without animation.
I don't think there's a way to disable the transition animation on TabBarView. As a workaround, you can use a Container that'll return different pages depending on the tab selected.
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(
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage>
with SingleTickerProviderStateMixin {
#override
void initState() {
super.initState();
tabController = TabController(length: 4, vsync: this);
}
var _homeScaffoldKey = Key("Scaffold Key");
var tabController;
var currentPage = 0;
#override
Widget build(BuildContext context) {
return new Scaffold(
key: _homeScaffoldKey,
body: _getCustomContainer(),
bottomNavigationBar: new Material(
color: Colors.blue,
child: new TabBar(
isScrollable: true,
indicatorColor: Color.fromRGBO(255, 25, 255, 0.0),
controller: tabController,
onTap: (value) {
setState(() {
currentPage = value;
});
},
tabs: <Widget>[
new Tab(
icon: new Icon(Icons.accessibility),
),
new Tab(
icon: new Icon(Icons.accessibility),
),
new Tab(
icon: new Icon(Icons.accessibility),
),
new Tab(
icon: new Icon(Icons.accessibility),
),
],
),
),
);
}
_getCustomContainer() {
switch (currentPage) {
case 0:
return page1();
case 1:
return page2();
case 2:
return page3();
case 3:
return page4();
}
}
page1() => Container(
color: Colors.redAccent,
child: Center(
child: Text("Page 1"),
),
);
page2() => Container(
color: Colors.greenAccent,
child: Center(
child: Text("Page 2"),
),
);
page3() => Container(
color: Colors.blueAccent,
child: Center(
child: Text("Page 3"),
),
);
page4() => Container(
color: Colors.yellowAccent,
child: Center(
child: Text("Page 4"),
),
);
}
Demo
Seems like this can be achieved using DefaultTabController easily as of 2022.
Here is my solution to this:
class _TabPageState extends State<TabPage>
with SingleTickerProviderStateMixin {
late TabController _tabController;
#override
void initState() {
super.initState();
// when initializing the `TabController` set `animationDuration` as `zero`.
_tabController =
TabController(length: 3, vsync: this, animationDuration: Duration.zero);
}
#override
Widget build(BuildContext context) {
return Container(
color: ColorPalette.white,
child: SafeArea(
top: false,
child: DefaultTabController(
length: 3,
child: Builder(builder: (context) {
return Scaffold(
bottomNavigationBar: TabBar(
controller: _tabController, // set the tab controller of your `TabBar`
enableFeedback: false,
onTap: (index) {
setState(() {});
},
indicatorColor: Colors.transparent,
tabs: [
TabItem(
selectedIndex: _tabController.index,
index: 0,
assetName: Assets.tabHome),
TabItem(
selectedIndex: _tabController.index,
index: 1,
assetName: Assets.tabCare),
TabItem(
selectedIndex: _tabController.index,
index: 2,
assetName: Assets.tabProfile),
],
),
body: Center(
child: TabBarView(
controller: _tabController, // set the controller of your `TabBarView`
physics: const NeverScrollableScrollPhysics(),
children: const [
ParentHomePage(),
ParentCarePage(),
ParentAccountPage()
],
),
),
);
}),
),
),
);
}
}
You Can Fix It by Go to MaterialApp and type
theme:new ThemeData(
splashColor:Colors.blue,
highlightColor: Colors.blue
)
what it mean if your tab background color blue you will change splashColor and highlightColor to blue that mean the animation doesn't disabled but it doesn't appear because the animation splashcolor and highlight will be blue such as Tab Background , I Hope I Help You