Search code examples
flutterdartdart-null-safety

Dart throws LateInitializationError even when I initialize variables in initState


I'm declaring two variables using the late keyword, so that I can initialize both of them in the initState function.

class _CustomNavBarState extends State<CustomNavBar>
    with TickerProviderStateMixin {

  late AnimationController _animationController;
  late Animation<double> _animation;

  @override
  void initState() {
    super.initState();
    AnimationController _animationController =
        AnimationController(vsync: this, duration: Duration(milliseconds: 500));
    Animation<double> _animation =
        Tween<double>(begin: 1, end: 0.8).animate(_animationController);
  }
//...

If initState gets called before any other function, why am I getting the following error?

LateIinitializationError: Field '_animation@17200479' has not been initialized.

Here's some more code:

class CustomNavBar extends StatefulWidget {
  const CustomNavBar(
      {required this.icons,
      required this.names,
      required this.onPressed,
      required this.activeIndex});
  final List<IconData> icons;
  final List<String> names;
  final Function(int) onPressed;
  final int activeIndex;

  @override
  _CustomNavBarState createState() => _CustomNavBarState();
}

class _CustomNavBarState extends State<CustomNavBar>
    with TickerProviderStateMixin {
  late AnimationController _animationController;
  late Animation<double> _animation;

  @override
  void didUpdateWidget(CustomNavBar oldWidget) {
    super.didUpdateWidget(oldWidget);
    if (oldWidget.activeIndex != widget.activeIndex) {
      _animate();
    }
  }

  void _animate() {
    _animationController.forward();
  }

  @override
  void initState() {
    super.initState();
    AnimationController _animationController =
        AnimationController(vsync: this, duration: Duration(milliseconds: 500));
    Animation<double> _animation =
        Tween<double>(begin: 1, end: 0.8).animate(_animationController);
  }

  @override
  Widget build(BuildContext context) {
    return Container(
      height: 90,
      decoration: BoxDecoration(
          gradient: LinearGradient(
        colors: [Theme.of(context).backgroundColor, Colors.black],
        begin: Alignment.topCenter,
        end: Alignment.bottomCenter,
      )),
      child: Row(
        mainAxisAlignment: MainAxisAlignment.spaceEvenly,
        children: [
          for (var i = 0; i < widget.icons.length; i++)
            TextButton(
                style:
                    TextButton.styleFrom(splashFactory: NoSplash.splashFactory),
                onPressed: () => widget.onPressed(i),
                child: ScaleTransition(
                    child: Column(
                        mainAxisAlignment: MainAxisAlignment.center,
                        children: [
                          Icon(
                            widget.icons[i],
                            size: 30,
                            color: i == widget.activeIndex
                                ? Theme.of(context).accentColor
                                : Colors.white70,
                          ),
                          Text(
                            widget.names[i],
                            style: TextStyle(
                              color: i == widget.activeIndex
                                  ? Theme.of(context).accentColor
                                  : Colors.white70,
                            ),
                          )
                        ]),
                    scale: _animation))
        ],
      ),
    );
  }
}



Solution

  • This is declaring a local variable:

    AnimationController _animationController =
        AnimationController(vsync: this, duration: Duration(milliseconds: 500));
    

    What you want is assign to your existing class member variable:

    _animationController =
        AnimationController(vsync: this, duration: Duration(milliseconds: 500));