How I do make my animation repeat when I click on it with animatedbuilder? flutter/dart

1.3k Views Asked by At

I'm working on a custom animation button. I want to repeat the animation every time the user taps on it. So when the user clicks on it, the container scales bigger. And returns to the normal size. And when the user clicks on it again it does it again. Right now the animation just scales up to the defined sized and stops. It doesn't do anything after that.

class CustomAnimation extends StatefulWidget {
  @override
  _CustomAnimationState createState() => _CustomAnimationState();
}

class _CustomAnimationState extends State<CustomAnimation> with SingleTickerProviderStateMixin {

  AnimationController _controller;

  @override
  void initState() {
    // TODO: implement initState

    _controller = AnimationController(
      vsync: this,
      duration: Duration(seconds: 2),
    );
    _controller.addListener(() {
      setState(() {
        //do something
      });
    });
    _controller.forward();
    super.initState();
  }

  @override
  void dispose() {
    // TODO: implement dispose
    _controller.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: AnimatedBuilder(
          animation: _controller.view,
          builder: (context,child){
            return Transform.scale(scale: _controller.value *.9,
                child: Container(
                  width: 200,
                  height: 200,
                  color: Colors.lightGreen[200],
                  child: Center(
                    child: Text('Animation test'),
                  ),
                ),
            );
          },
        ),

      )
    );
  }
}
1

There are 1 best solutions below

0
chunhunghan On BEST ANSWER

You can copy paste run full code below
You can listen AnimationStatus.completed and call _controller.reverse()
And use InkWell call _controller.forward();

 animation = Tween<double>(begin: 1.0, end: 1.2).animate(_controller)
      ..addStatusListener((status) {
        if (status == AnimationStatus.completed) {
          _controller.reverse();
        }
      });
...   
return Transform.scale(
            scale: animation.value,
            child: InkWell(
              onTap: () {
                _controller.forward();
              },      

working demo

enter image description here

full code

import 'package:flutter/material.dart';

class CustomAnimation extends StatefulWidget {
  @override
  _CustomAnimationState createState() => _CustomAnimationState();
}

class _CustomAnimationState extends State<CustomAnimation>
    with SingleTickerProviderStateMixin {
  AnimationController _controller;
  Animation<double> animation;

  @override
  void initState() {
    _controller =
        AnimationController(vsync: this, duration: Duration(seconds: 2));
    _controller.addListener(() {
      setState(() {
        //do something
      });
    });

    _controller.forward();
    animation = Tween<double>(begin: 1.0, end: 1.2).animate(_controller)
      ..addStatusListener((status) {
        if (status == AnimationStatus.completed) {
          _controller.reverse();
        }
      });
    super.initState();
  }

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        body: Center(
          child: AnimatedBuilder(
            animation: animation,
            builder: (context, child) {
              return Transform.scale(
                scale: animation.value,
                child: InkWell(
                  onTap: () {
                    _controller.forward();
                  },
                  child: Container(
                    width: 200,
                    height: 200,
                    color: Colors.lightGreen[200],
                    child: Center(
                      child: Text('Animation test'),
                    ),
                  ),
                ),
              );
            },
          ),
        ));
  }
}

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
        visualDensity: VisualDensity.adaptivePlatformDensity,
      ),
      home: CustomAnimation(),
    );
  }
}