Animate a color periodically in flutter

You can use an infinite while loop, don't think this is the best way of doing this, but it gets the job done.

I have a Color Changing class

class ColorChanger extends StatefulWidget {


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

class _ColorChangerState extends State<ColorChanger>
    with SingleTickerProviderStateMixin {
  AnimationController _animationController;
  Animation _colorTween;

  @override
  void initState() {
    _animationController = AnimationController(
        vsync: this, duration: Duration(milliseconds: 1999));
    _colorTween = ColorTween(begin: Colors.blue, end: Colors.blueGrey)
        .animate(_animationController);
    changeColors();
    super.initState();
  }

  Future changeColors() async {
    while (true) {
      await new Future.delayed(const Duration(seconds: 2), () {
        if (_animationController.status == AnimationStatus.completed) {
          _animationController.reverse();
        } else {
          _animationController.forward();
        }
      });
    }
  }

  @override
  Widget build(BuildContext context) {
    return AnimatedBuilder(
      animation: _colorTween,
      builder: (context, child) => Container(
            color: _colorTween.value,
          ),
    );
  }
}

This is a rough example, but should lead you in the right direction.

Please see ColorTween Class


I would suggest using the AnimatedContainer. This widget allows you to build it with a particular atribute like color and when you rebuild it with a different value it performs linear interpolation between those values.

@override
  Widget build(BuildContext context) {
    return AnimatedContainer(
      width: 100,
      height: 100,
      duration: _animationDuration,
      color: _color,
    );
  }

Then you just have to rebuild the widget with a different color:

void _changeColor() {
    final newColor = _color == Colors.blue ? Colors.blueGrey : Colors.blue;
    setState(() {
      _color = newColor;
    });
  }

The make it periodically I would use a timer class:

_timer = Timer.periodic(_animationDuration, (timer) => _changeColor());

The whole code:

import 'dart:async';

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

class AnimationTest extends StatefulWidget {
  @override
  _AnimationTestState createState() => _AnimationTestState();
}

class _AnimationTestState extends State<AnimationTest> {
  final _animationDuration = Duration(seconds: 2);
  Timer _timer;
  Color _color;

  @override
  void initState() {
    super.initState();
    _timer = Timer.periodic(_animationDuration, (timer) => _changeColor());
    _color = Colors.blue;
  }

  void _changeColor() {
    final newColor = _color == Colors.blue ? Colors.blueGrey : Colors.blue;
    setState(() {
      _color = newColor;
    });
  }

  @override
  Widget build(BuildContext context) {
    return AnimatedContainer(
      width: 100,
      height: 100,
      duration: _animationDuration,
      color: _color,
    );
  }

  @override
  void dispose() {
    super.dispose();
    _timer.cancel();
  }
}

Tags:

Flutter