Home > Software design >  How to perform arithmetic operation on Late Variable in Flutter?
How to perform arithmetic operation on Late Variable in Flutter?

Time:10-08

Defining a variable without initialising it.
AnimationController _controller;
An error is thrown: Non-nullable instance field '_controller' must be initialized.

On the internet, there are 3 ways to solve this problem but all has its limitation.

Solution_1. late AnimationController _controller;
Drawback: Arithmetic operations like this can't be performed, sum = (_controller.value) * 200, sum = (_controller!.value)! * 200, sum = (_controller?.value)! * 200 .

Solution_2. AnimationController _controller = AnimationController(vsync: this, duration: Duration(seconds: 1)); //Defining & Initialising globally inside a class
Drawback: vsync throws an error as it's not inside any function. (Invalid reference to 'this' expression.

Solution_3. AnimationController _controller = AnimationController(vsync: this, duration: Duration(seconds: 1)); //Defining & Initialising inside initState()
Drawback: can't use _controller inside any other method.

Due to all these issues I am not able to perform arithmetic operation using _controller. Is there any way to solve this problem? Here's my code for reference-

import 'dart:math';
import 'package:flutter/material.dart';

class HomeScreen extends StatefulWidget {
  @override
  _HomeScreenState createState() => _HomeScreenState();
}

class _HomeScreenState extends State<HomeScreen>
    with SingleTickerProviderStateMixin {
  int leftDice = 1, rightDice = 1;
  Random random = Random();
  late AnimationController _controller;

  @override
  void initState() {
    super.initState();
    animate();
    print("Init called");
  }

  @override
  void dispose() {
    super.dispose();
    _controller?.dispose();
  }

  void animate() {
    print("Animate called");
    AnimationController _controller =
        AnimationController(vsync: this, duration: Duration(seconds: 1));
    _controller.addListener(() {
      setState(() {});
    });
    _controller.addStatusListener((status) {
      if (status == AnimationStatus.completed) {
        print("Compleated");
        _controller.reverse();
      }
    });
  }

  void roll() {
    _controller?.forward();
    setState(() {
      leftDice = random.nextInt(6)   1;
      rightDice = random.nextInt(6)   1;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("Dicee"),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            Row(
              children: [
                Expanded(
                    child: Padding(
                  padding: EdgeInsets.all(15),
                  child: GestureDetector(
                    onDoubleTap: roll,
                    child: Image(
                      height: 200 - (_controller!.value)! * 200,
                      image: AssetImage('assets/images/dice-$leftDice.png'),
                    ),
                  ),
                )),
                Expanded(
                    child: Padding(
                  padding: EdgeInsets.all(15),
                  child: GestureDetector(
                    onDoubleTap: roll,
                    child: Image(
                      image: AssetImage('assets/images/dice-$rightDice.png'),
                    ),
                  ),
                ))
              ],
            ),
            ElevatedButton(onPressed: roll, child: Text("Roll Dice"))
          ],
        ),
      ),
    );
  }
}

CodePudding user response:

You've already declared _controller in the class, You shouldn't declare it in animate again.

Try this:

  void animate() {
    print("Animate called");
    _controller =
        AnimationController(vsync: this, duration: Duration(seconds: 1));
    _controller.addListener(() {
      setState(() {});
    });
    _controller.addStatusListener((status) {
      if (status == AnimationStatus.completed) {
        print("Compleated");
        _controller.reverse();
      }
    });
  }
  • Related