Non-nullable instance field '_tabController' must be initialized - flutter

I frustated over this code
_GenresListState(this.genres);
why it keeps showing the alert of _tabController must be initialized, im already put late constructor but the error is still going, this is the code where i put it:
class _GenresListState extends State<GenresList> with SingleTickerProviderStateMixin {
final List<Genre> genres;
_GenresListState(this.genres);
TabController _tabController;
#override
void initState() {
super.initState();

If you provide to initialize before reading _tabController, you can include late
late TabController _tabController;
#override
void initState() {
super.initState();
_tabController = TabController(length: length, vsync: this)
More about working with tabs

You have to initialize the tab controller, because it needs to populate you current layout with the accurate data needed for the screen to be built.
You can't give it values after the screen has been built, and flutter won't let you do it either because it needs those values.
late TabController tabController;
#override
void initState() {
tabController = TabController(length: 2, vsync: this);
super.initState();
}
#override
void dispose() {
tabController.dispose();
super.dispose();
}
Notice that the value had to be stated in the initState so when the layout is being built, it builds correctly.
For you use case if you want to build with the list of genres, you do something like this
late TabController tabController;
#override
void initState() {
tabController = TabController(length: genres.length, vsync: this);
super.initState();
}
#override
void dispose() {
tabController.dispose();
super.dispose();
}

Related

LateError (LateInitializationError: Field '_state#590051772' has not been initialized.)

I don't understand why I'm catching an error in _mapController:
final MapController _mapController = MapController();
#override
void initState() {
super.initState();
_mapController.move(widget.latLng, _mapController.zoom);
}
I don't know but try like this ? :
late MapController _mapController;
#override
void initState() {
_mapController = MapController();
_mapController.move(widget.latLng, _mapController.zoom);
super.initState();
}
Try below code
MapController? _mapController;
//or try this-> MapController _mapController;
#override
void initState() {
super.initState();
_mapController.move(widget.latLng, _mapController.zoom);
}
I think the problem arises because you start using the mapcontroller before the build function starts which has the necessary configuration for the map. Try to put this line
_mapController.move(widget.latLng, _mapController.zoom);
inside a method for example (_moveMap) and call it inside the build function when pressing a button.
like this:
child: ElevatedButton(
child:Icon(Icons.location_on_outlined,
color: Colors.blue,) ,
onPressed:_moveMap ,
)),

I am trying to use tab controller in flutter how can I access it inside the build context

I am trying to use a tab bar controller , what is the right way to add it
Just declare the tabController globally inside your state class and initialise it inside init state as you did, then you can access it inside your build method.
late TabController tabController;
void initState(){
tabController=TabController(vsync:this,length:3);
}
now use accordingly tab controller inside build method.
Try to declare tabController globally inside your state class and init it inside init state see the documentation for more details :
class _JobApplication... extendes State<...> ..{
late TabController _tabController;
#override
void initState() {
super.initState();
_tabController = TabController(vsync: this, length: 3);
}
}
declare in state
late TabController _tabController;
Assign in initstate
#override
void initState() {
super.initState();
_tabController = TabController(vsync: this, length: 3);
}

Why are the variables in initState not acessible?

I want to create a TextController in the initState and then dispose of it like a good boy in dispose. But for some reason, the controller is not avaiable outside of the intiState:
class _InputFieldEnterThingState extends State<InputFieldEnterThing> {
#override
void initState() {
TextEditingController textController =
TextEditingController(text: 'placeholder');
super.initState();
}
#override
void dispose() {
textController.dispose();
super.dispose();
}
It tells me "textController" is not defined in dispose() ... same, if I try using it in the build method. It's, as if the varialbe is strictly local in initState. I feel I'm missing something super obvious, but cannot find it.
The textController is a local variable in the initState method, you need to make him global and the dispose method will recognize him.
The way to do that:
class _InputFieldEnterThingState extends State<InputFieldEnterThing> {
TextEditingController textController; // make him global
#override
void initState() {
textController = // without redefine
TextEditingController(text: 'placeholder');
super.initState();
}
#override
void dispose() {
textController.dispose();
super.dispose();
}
Since you declared the variable textController inside initState the variable is only accessible in initState. If you want to access textController e.g. in dispose, you have to declare it outside the initState.
class _InputFieldEnterThingState extends State<InputFieldEnterThing> {
late TextEditingController textController;
#override
void initState() {
textController = TextEditingController(text: 'placeholder');
super.initState();
}
#override
void dispose() {
textController.dispose();
super.dispose();
}

How to make a variable final and assign it a value inside initState()

What's the best way to make the AnimationController final in a StatefulWidget, the below codes give error.
final AnimationController _controller; // I want to keep it final
#override
void initState() {
super.initState();
_controller = AnimationController(vsync: this); // error
}
That is not possible. initState cannot be used to initialize final variables.
Even then, there is no way to assign an AnimationController to a final property as it depends on this.
As explained by RĂ©mi Rousselet's answer, you can't.
If you absolutely need _controller to be final (why?), then you could work around it by wrapping it in another object (e.g. a custom class, a List, ...) and mutating that. For example:
class Boxed<T> {
T value;
}
final _controller = Boxed<AnimationController>();
#override
void initState() {
super.initState();
_controller.value = AnimationController(vsync: this);
}
You can now do that with late keyword.
late final AnimationController _controller;
#override
void initState() {
super.initState();
_controller = AnimationController(vsync: this);
}

How to hot-reload State fields?

How to hot-reload fields of a State subclass in Flutter?
I know that the modifying the initial value of fields isn't taken into account during hot-reload and that I can use hot-restart for them. But this is painfully slow.
Is there any way to ease the process?
A typical use-case would be animations, especially AnimationController. As it is stored inside a State field, but we usually want to iterate over its duration. Example:
class MyAnim extends StatefulWidget {
#override
_MyAnimState createState() => _MyAnimState();
}
class _MyAnimState extends State<MyAnim> with SingleTickerProviderStateMixin {
AnimationController animationController;
#override
void initState() {
animationController =
AnimationController(vsync: this, duration: const Duration(seconds: 1));
super.initState();
}
#override
void dispose() {
animationController.dispose();
super.dispose();
}
#override
Widget build(BuildContext context) {
return Container();
}
}
State provides a custom lifecycle hook for hot-reloads: reassemble
You can freely override that method to have custom hot-reload behaviors. Don't worry, this method will never be called in production.
With a small tweak you'd get the following:
class _MyAnimState extends State<MyAnim> with SingleTickerProviderStateMixin {
AnimationController animationController;
#override
void initState() {
animationController = AnimationController(vsync: this);
_initializeFields();
super.initState();
}
void _initializeFields() {
animationController.duration = const Duration(seconds: 1);
}
#override
void reassemble() {
_initializeFields();
super.reassemble();
}
#override
void dispose() {
animationController.dispose();
super.dispose();
}
#override
Widget build(BuildContext context) {
return Container();
}
}
Now, whenever you modify your State class, it will correctly update AnimationController's duration.