DefaultTabBarController with flutter - 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);
}),
]),
))

Related

Returns null value when using Localizations for multi-language system (Flutter, Dart)

I need to implement two languages in my application using packages (localizations).
In my application, there are 1 main view containing 4 tab views (Home(),Graph(),History(),GoalSetting), and 1 view(Record()) which are navigated by floating button.
My problem is, although AppLocalizations.of(context)!.registeredWord is correctly implemented at the main view and view from floating button, it returns "Null check operator used on a null value" at 4 tab views.
I am wondering how I can fix this.
Relating part of my code of main view is shown below. If you need additional information, please let me know.
import 'package:bottom_navy_bar/bottom_navy_bar.dart';
import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
import 'package:flutter_localizations/flutter_localizations.dart';
void main() async {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return const MaterialApp(
localizationsDelegates: [
AppLocalizations.delegate,
GlobalMaterialLocalizations.delegate,
GlobalWidgetsLocalizations.delegate,
GlobalCupertinoLocalizations.delegate,
],
supportedLocales: [
Locale('ja', ''),
Locale('en', ''),
],
title: 'Flutter Demo',
home: MyHomePage(),
);
}
class MyHomePage extends StatefulWidget {
const MyHomePage({Key? key}) :super(key: key);
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
PageController _pageController = PageController(initialPage: 0);
#override
void initState() {
super.initState();
_pageController = PageController();
}
int _currentIndex = 0;
List<Widget> viewList = [
Home(),
const Graph(),
History(),
GoalSetting()
];
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: viewList[_currentIndex],
floatingActionButtonLocation:
FloatingActionButtonLocation.endFloat,
floatingActionButton: SizedBox(
width: 60,
child: FloatingActionButton(
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => Record(),
));
},
child: const Icon(Icons.add),
)),
bottomNavigationBar: BottomNavyBar(
selectedIndex: _currentIndex,
showElevation: true,
containerHeight: 70,
itemCornerRadius: 24,
curve: Curves.easeIn,
onItemSelected: (index) => setState(() => _currentIndex = index),
items: <BottomNavyBarItem>[
BottomNavyBarItem(
icon: const Icon(Icons.home),
title: Text(AppLocalizations.of(context)!.home), //OK
activeColor: Colors.blueGrey,
textAlign: TextAlign.center,
),
BottomNavyBarItem(
icon: const Icon(Icons.show_chart),
title: Text(AppLocalizations.of(context)!.graph), //OK
activeColor: Colors.blueGrey,
textAlign: TextAlign.center,
),
BottomNavyBarItem(
icon: const Icon(Icons.history),
title: Text(
AppLocalizations.of(context)!.history,
),
activeColor: Colors.blueGrey,
textAlign: TextAlign.center,
),
BottomNavyBarItem(
icon: const Icon(Icons.flag),
title: Text(AppLocalizations.of(context)!.goals), //OK
activeColor: Colors.blueGrey,
textAlign: TextAlign.center,
),
],
),
),
);
}
}
Additionally, One example code of tab views is shown below.
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
import 'package:hive_flutter/hive_flutter.dart';
import 'package:provider/provider.dart';
import 'package:stylerecord/Model/goal.dart';
import 'Model/record.dart';
import 'Model/sqlite.dart';
import 'main.dart';
class Home extends StatefulWidget {
#override
_HomeState createState() => _HomeState();
}
class _HomeState extends State<Home> {
#override
Widget build(BuildContext context) {
return WatchBoxBuilder(
box: boxList[0],
builder: (context, recordHiveBox) {
return WatchBoxBuilder(
box: boxList[1],
builder: (context, goalHiveBox) {
return Consumer<GoalData>( //The relevant error-causing widget
builder: (context, goalData, child) {
return Consumer<RecordData>(
builder: (context, recordData, child) {
RecordHive lastRecord =
recordHiveBox.getAt(recordHiveBox.length - 1);
return Scaffold(
appBar: AppBar(
title: Text('StyleRecord'),
backgroundColor: Colors.blueGrey[900]),
body: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
DefaultTextStyle.merge(
style: TextStyle(
fontSize: 20.0,
fontFamily: 'MPLUSRounded1c'),
child: Column(
mainAxisAlignment:
MainAxisAlignment.spaceEvenly,
children: [
Text(AppLocalizations.of(context)!.part), //Error("this was the stack")
Text(AppLocalizations.of(context)!.weight),
........
Text(AppLocalizations.of(context)!.ankle),
Padding(
padding: const EdgeInsets.all(16))
])),
DefaultTextStyle.merge(
style: TextStyle(
fontSize: 25.0,
fontFamily: 'MPLUSRounded1c'),
child: Column(
mainAxisAlignment:
MainAxisAlignment.spaceEvenly,
children: <Widget>[
// Text(AppLocalizations.of(context)!
// .lasTime),
Text(
'${lastRecord.measurement[0]} kg'),
...
Text(
'${lastRecord.measurement[8]} cm'),
Padding(
padding: const EdgeInsets.all(20))
])),
DefaultTextStyle.merge(
style: TextStyle(
fontSize: 20.0,
fontFamily: 'MPLUSRounded1c'),
child: Column(
mainAxisAlignment:
MainAxisAlignment.spaceEvenly,
children: [
// Text(AppLocalizations.of(context)!
// .toGoal),
(goalHiveBox.isEmpty)
? Text(
L10n.of(context)!
.noData)
: goalData.TextDif(
recordHiveBox.getAt(
recordHiveBox.length - 1),
goalHiveBox.getAt(0),
0),
...
(goalHiveBox.isEmpty)
? Text(
L10n.of(context)!
.noData)
: goalData.TextDif(
recordHiveBox.getAt(
recordHiveBox.length - 1),
goalHiveBox.getAt(0),
8),
Padding(
padding: const EdgeInsets.all(16))
]))
]),
);
},
);
},
);
});
});
}
}

Flutter SingleChildScrollView is not stopping in the middle but bouncing to the edge

In demo, even if I don't use drawer or appBar it doesn't matter. Any scrollview is not stopping in the middle. Even if it's a ListView or column in a SingleChildScrollView, it doesn't matter. I can't scroll normally. It suddenly bounces to the other edge.
The reason I use option + shift is to show when I release mouse.
https://www.youtube.com/watch?v=GqlQL_rl3Xc
Test Demo:
import 'xxxx/widgets/app-bar.dart';
import 'xxxx/widgets/drawer.dart';
import 'package:flutter/material.dart';
class PageHome extends StatefulWidget {
PageHome({Key? key}) : super(key: key);
#override
_PageHomeState createState() => _PageHomeState();
}
class _PageHomeState extends State<PageHome> {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: IAppBar(
title: "Home",
),
drawer: AppDrawer(
index: AppDrawer.DRAWER_INDEX_HOME,
),
body: SingleChildScrollView(
controller: ScrollController(),
child: Container(
decoration: BoxDecoration(
gradient: LinearGradient(
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
colors: [
Colors.yellow,
Colors.teal,
Colors.purple,
Colors.blue,
Colors.red
])),
child: Column(
children: [
Container(height: 3000),
],
),
),
),
);
} f
}
Main dart:
class MyApp extends StatefulWidget {
MyApp();
#override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
#override
void initState() {
super.initState();
}
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'CT',
theme: ThemeData(
brightness: Brightness.light,
backgroundColor: backgroundColor,
primaryColor: primaryColor,
accentColor: accentColor,
textTheme: GoogleFonts.ubuntuTextTheme().copyWith(
headline1: GoogleFonts.ubuntuTextTheme().headline1?.copyWith(
fontSize: 24,
fontWeight: FontWeight.w900,
color: Colors.black)),
),
onGenerateRoute: ARouter.generateRoute);
}
}
class Splash extends StatefulWidget {
const Splash({Key? key}) : super(key: key);
#override
_SplashState createState() => _SplashState();
}
class _SplashState extends State<Splash> {
#override
void initState() {
super.initState();
WidgetsBinding.instance?.addPostFrameCallback((timeStamp) async {
if ((!await FlutterSecureStorage().containsKey(key: "intro"))) {
Navigator.pushReplacementNamed(context, ARouter.routeIntro);
return;
}
if (await getJWT() == null) {
Navigator.pushReplacementNamed(context, ARouter.routeAuth);
return;
}
if (await validateToken())
Navigator.pushReplacementNamed(context, ARouter.routeHome);
else
Navigator.pushReplacementNamed(context, ARouter.routeAuth);
});
}
#override
Widget build(BuildContext context) {
return Container(
color: Colors.white,
child: Stack(
children: [
Image.asset("assets/images/bg.png"),
Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
CircularProgressIndicator(
strokeWidth: 6,
),
Container(height: 24),
Center(
child: Text(
"Loading",
style: TextStyle(
fontSize: 24,
color: Colors.black,
decoration: TextDecoration.none),
)),
],
),
],
),
);
}
}

No TabController for TabBar

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

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

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