`vsync` property in TabController constructor
DartTabcontrolFlutterDart Problem Overview
According to this: sample code
I created my own implementation of TabController:
void main() {
runApp(new MyApp());
}
class MyApp extends StatefulWidget {
@override
_MyAppState createState() => new _MyAppState();
}
class _MyAppState extends State<MyApp> {
TabController _tabController;
@override
void initState() {
super.initState();
_tabController = new TabController(vsync: this, length: choices.length);
}
@override
void dispose() {
_tabController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return new MaterialApp(
home: new Scaffold(
bottomNavigationBar: new Material(
color: Colors.blue,
child: new TabBar(
controller: _tabController,
isScrollable: false,
tabs: choices.map((Choice choice) {
return new Tab(
text: null,
icon: new Icon(choice.icon),
);
}).toList(),
),
),
appBar: new AppBar(
title: const Text('Swap'),
),
body: new TabBarView(
controller: _tabController,
children: choices.map((Choice choice) {
return new Padding(
padding: const EdgeInsets.all(16.0),
child: new ChoiceCard(choice: choice),
);
}).toList(),
),
),
);
}
}
In line: _tabController = new TabController(vsync: this, length: choices.length);
I got error this message:
> error: The argument type '_MyAppState' can't be assigned to the parameter type 'TickerProvider'. (argument_type_not_assignable at [swap] lib/main.dart:24)
What is wrong with my code?
Dart Solutions
Solution 1 - Dart
Add with TickerProviderStateMixin
to the end of your State
’s class declaration.
Solution 2 - Dart
Simply add with TickerProviderStateMixin
at the end of extends state class as follows:
class _MyAppState extends State<MyApp> with TickerProviderStateMixin {
//...
}
Solution 3 - Dart
As Answered earlier adding the mixin
, TickerProviderStateMixin
should do the job or you can also use SingleTickerProviderStateMixin
if you only need a Single Ticker
.
> But what is Does TickerProviders
really do?
vsync
takes a TickerProvider
as an argument , that's why we use SingleTickerProviderStateMixin
and as the named describes TickerProvider
provides Ticker
which simply means it tells our app about the Frame update(or Screen Update), so that our AnimationController
can generate a new value and we can redraw the animated widget.
Solution 4 - Dart
Question is very generic, so need to describe more
Vsync used for
-
vsync is the property that represents the TickerProvider (i.e., Tick is similar to clock's tick which means that at every certain duration TickerProvider will render the class state and redraw the object.)
-
vsync property is required only on that constructor which requires to render its class state at every certain off-set time when we need to render our components or widgets to redraw and reflect the UI.
-
vsync can be used with the classes which require certain transition or animation to re-render to draw different objects.
Internal Implementation
TabController({ int initialIndex = 0, @required this.length, @required TickerProvider vsync })
: assert(length != null && length >= 0),
assert(initialIndex != null && initialIndex >= 0 && (length == 0 || initialIndex < length)),
_index = initialIndex,
_previousIndex = initialIndex,
_animationController = AnimationController.unbounded(
value: initialIndex.toDouble(),
vsync: vsync,
);
TabController
uses AnimationController
internally for the rendering of the tab bar state
Solution 5 - Dart
All you have to do is add to this one - SingleTickerProviderStateMixin
next to State<MyApp>
As @Shubham-Soni said above
Just change this line:
_MyAppState extends State<MyApp>
To this:
_MyAppState extends State<MyApp>
with SingleTickerProviderStateMixin
Here is the complete example of how to do this
class MyApp extends StatefulWidget {
const MyApp({Key key}) : super(key: key);
@override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp>
with SingleTickerProviderStateMixin {
TabController tabController;
void initState() {
tabController =
TabController(length: tabsList.length, vsync: this, initialIndex: 0);
super.initState();
}
@override
Widget build(BuildContext context) {
// TODO: implement build
throw UnimplementedError();
}
}
Solution 6 - Dart
Add TickerProviderStateMixin at the end of class state
Here is the full example
@override
_HomeState createState() => _HomeState();
}
class _HomeState extends State<Home> with TickerProviderStateMixin {
MotionTabController? _tabController;
@override
void initState() {
super.initState();
_tabController = new MotionTabController(initialIndex: 1, vsync: this);
}
@override
void dispose() {
super.dispose();
_tabController!.dispose();
}
@override
Widget build(BuildContext context) {
// TODO: implement build
throw UnimplementedError();
}
}
Solution 7 - Dart
In GetX
I found a solution just add with SingleGetTickerProviderMixin to be the full code as the below one:
import 'package:get/get.dart';
import 'package:flutter/material.dart';
class ControllerViewModel extends GetxController with SingleGetTickerProviderMixin {
AnimationController _controller;
@override
void onInit() {
// TODO: implement onInit
super.onInit();
_controller = AnimationController(
vsync: this,
duration: const Duration(
milliseconds: 2500,
),
);
}
}
Solution 8 - Dart
The above answers are correct but you have to declare a tabbar in class and initialize the tabbar from iniState, else the vsync variable doesn't accept 'this' Following code may help you.
class _MatchesState extends State<Matches> with SingleTickerProviderStateMixin {
TabController? tabController;
@override
void initState() {
tabController = TabController(
length: 2,
vsync: this,
initialIndex: 0,
);
super.initState();
}
Solution 9 - Dart
Add any of these SingleTickerProviderStateMixin/ TickerProviderStateMixin mixins at the end of the statement like below:
Eg:
>class _ListingViewState extends State