dontknowhy
dontknowhy

Reputation: 2896

How to change the background continuously in flutter

I know how to change the background but I need it to be changing continuously.

How do I achieve this?

Upvotes: 13

Views: 13384

Answers (4)

Kdon
Kdon

Reputation: 1235

Another option is to use ColorTween.

Here is a widget that can be placed as a background and will continuously animate nicely between two colors which are passed in as arguments.


import 'package:flutter/material.dart';

class AnimatedColorBackground extends StatefulWidget {
  const AnimatedColorBackground(
      {Key? key, required this.primaryColor, required this.secondaryColor})
      : super(key: key);

  final Color primaryColor;
  final Color secondaryColor;

  @override
  State<AnimatedColorBackground> createState() =>
      _AnimatedColorBackgroundState();
}

class _AnimatedColorBackgroundState extends State<AnimatedColorBackground>
    with SingleTickerProviderStateMixin {
  late AnimationController _controller;
  late Animation<Color?> _colorTween;

  @override
  void initState() {
    super.initState();
    _controller = AnimationController(
        duration: Duration(
          seconds: 10,
        ),
        vsync: this);
    _colorTween =
        ColorTween(begin: widget.primaryColor, end: widget.secondaryColor)
            .animate(
                CurvedAnimation(parent: _controller, curve: Curves.easeOutSine))
          ..addStatusListener((status) {
            if (status == AnimationStatus.completed) {
              _controller.reverse();
            }
            if (status == AnimationStatus.dismissed) {
              _controller.forward();
            }
          });
    _controller.forward();
  }

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

  @override
  Widget build(BuildContext context) {
    return Container(
      color: _colorTween.value,
    );
  }
}

Upvotes: 0

Jamie Blair
Jamie Blair

Reputation: 9

I would instead initiate the transition in initState method as such:

@override
  void initState() {
    super.initState();

    Future.delayed(const Duration(milliseconds: 500), () {
      setState(() {
        bottomColor = Colors.blue;
      });
    });
  }

DISCLAIMER: this answer was inspired by the two above

Upvotes: 0

RHS.Dev
RHS.Dev

Reputation: 452

To auto animate the gradient just add this block of code in @override Widget build(BuildContext context) {} method of SeriForte's code.

Future.delayed(const Duration(milliseconds: 10), () {
  setState(() {
    bottomColor = Colors.blue;
  });
});

Upvotes: 11

SeriForte
SeriForte

Reputation: 700

you could use an AnimatedContainer and reset the target color when the animation is over. For a smooth Transition, I suggest a List of Colors you can loop over, you can do the same with the Alignment.

Example:

enter image description here

Source Code for the Example:

import 'package:flutter/material.dart';

class AnimatedGradient extends StatefulWidget {
  @override
  _AnimatedGradientState createState() => _AnimatedGradientState();
}

class _AnimatedGradientState extends State<AnimatedGradient> {
  List<Color> colorList = [
    Colors.red,
    Colors.blue,
    Colors.green,
    Colors.yellow
  ];
  List<Alignment> alignmentList = [
    Alignment.bottomLeft,
    Alignment.bottomRight,
    Alignment.topRight,
    Alignment.topLeft,
  ];
  int index = 0;
  Color bottomColor = Colors.red;
  Color topColor = Colors.yellow;
  Alignment begin = Alignment.bottomLeft;
  Alignment end = Alignment.topRight;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        body: Stack(
      children: [
        AnimatedContainer(
          duration: Duration(seconds: 2),
          onEnd: () {
            setState(() {
              index = index + 1;
              // animate the color
              bottomColor = colorList[index % colorList.length];
              topColor = colorList[(index + 1) % colorList.length];

              //// animate the alignment
              // begin = alignmentList[index % alignmentList.length];
              // end = alignmentList[(index + 2) % alignmentList.length];
            });
          },
          decoration: BoxDecoration(
              gradient: LinearGradient(
                  begin: begin, end: end, colors: [bottomColor, topColor])),
        ),
        Positioned.fill(
          child: IconButton(
            icon: Icon(Icons.play_arrow),
            onPressed: () {
              setState(() {
                bottomColor = Colors.blue;
              });
            },
          ),
        )
      ],
    ));
  }
}

Upvotes: 35

Related Questions