Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Animate a color periodically in flutter

Tags:

flutter

I have a container widget that I try to animate from Colors.blue to Colors.blueGrey and back periodically every 2 seconds.

How can I most easily tackle this in Flutter?

like image 969
Kasper Avatar asked May 09 '19 12:05

Kasper


People also ask

How do you animate colors in Flutter?

Now let us modify the application, such that the color toggles when button is pressed. We shall use controller. reverse() function to reverse the animation. When you run this application and click on the colored button, color animation toggles using controller.

What are staggered animations in Flutter?

A staggered animation consists of sequential or overlapping animations. To create a staggered animation, use multiple Animation objects. One AnimationController controls all of the Animation s. Each Animation object specifies the animation during an Interval .


Video Answer


2 Answers

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

like image 61
Tinus Jackson Avatar answered Oct 18 '22 03:10

Tinus Jackson


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();
  }
}
like image 20
Karol Lisiewicz Avatar answered Oct 18 '22 03:10

Karol Lisiewicz