flutter button background colour animation

How to Animate the Flutter Button with Examples

Why add an animation to the Flutter Buttons

Adding animation to Flutter Button can make them feel more responsive and engaging to users. Animations can help provide visual feedback when a button is pressed, indicating that the user’s action has been registered. By making the user interface more dynamic and interactive, animations can enhance the overall user experience and make the app feel more polished.

In addition to enhancing the user experience, animations can also serve a functional purpose. For example, animating the elevation of a button when it is pressed can create the illusion of depth, making the button appear more clickable and drawing the user’s attention to it. This can be especially useful in interfaces where buttons need to stand out, such as in forms or dialogs.

Overall, adding animations to Flutter buttons is a great way to improve the user experience and create a more polished, professional-looking app. By making buttons more responsive and engaging, animations can help users feel more in control and create a sense of satisfaction when using the app.

Animating Flutter Buttons: Properties That Can Be Animated

Flutter provides a number of properties that can be animated for buttons. Some of the commonly animated properties for buttons include:

  1. backgroundColor – The background colour of the button can be animated to change colour on tap or other user interactions.
  2. foregroundColor – The colour of the text or icon within the button can also be animated.
  3. elevation – The elevation of the button can be animated to create a “pressed” effect on tap.
  4. borderRadius – The border-radius of the button can be animated to create a more dynamic shape.
  5. scale – The size of the button can be animated to create a zoom-in effect on tap.

These are just a few examples of the properties that can be animated for buttons in Flutter. With a bit of creativity, you can create all kinds of custom animations and effects for your buttons.

How to animate an ElevatedButton elevation on tap in Flutter

To animate the elevation of an ElevatedButton in Flutter when it is tapped, you can use the AnimatedContainer widget to create a smooth transition from the original elevation value to a new elevation value. Here is an example implementation of a custom widget:

import 'package:flutter/material.dart';

class AnimatedElevatedButton extends StatefulWidget {
  final String label;
  final VoidCallback onPressed;

  const AnimatedElevatedButton({
    Key? key,
    required this.label,
    required this.onPressed,
  }) : super(key: key);

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

class _AnimatedElevatedButtonState extends State<AnimatedElevatedButton> {
  double _elevation = 20.0;

  @override
  Widget build(BuildContext context) {
    return GestureDetector(
      onTapDown: _onTapDown,
      onTapUp: _onTapUp,
      onTapCancel: _onTapCancel,
      child: AnimatedContainer(
        duration: Duration(milliseconds: 200),
        curve: Curves.easeInOut,
        decoration: BoxDecoration(
          borderRadius: BorderRadius.circular(8),
          boxShadow: [
            BoxShadow(
              color: Colors.grey[400]!,
              offset: Offset(0, _elevation),
              blurRadius: _elevation,
            )
          ],
        ),
        child: ElevatedButton(
          onPressed: widget.onPressed,
          child: Text(widget.label),
          style: ElevatedButton.styleFrom(
            elevation: 0,
            shape: RoundedRectangleBorder(
              borderRadius: BorderRadius.circular(8),
            ),
            padding: EdgeInsets.symmetric(vertical: 10, horizontal: 24),
          ),
        ),
      ),
    );
  }

  void _onTapDown(TapDownDetails details) {
    setState(() {
      _elevation = 2.0;
    });
  }

  void _onTapUp(TapUpDetails details) {
    setState(() {
      _elevation = 20.0;
    });
    widget.onPressed();
  }

  void _onTapCancel() {
    setState(() {
      _elevation = 20.0;
    });
  }
}

In this implementation, we set the initial _elevation value to 20.0 to give the button an elevated appearance. When the user taps down on the button, we set the _elevation value to 2.0, which is the new elevation value we want to animate to. When the user lifts their finger from the button or cancels the tap, we set the _elevation value back to the original value of 20.0.

Note that we swap the values of _onTapDown and _onTapUp methods, as we want to reduce the elevation to 2.0 when the button is pressed and restore it back to 20.0 when it is released.

We wrap the ElevatedButton in an AnimatedContainer and use the _elevation value to set the boxShadow values, which creates the elevation effect. We also set the duration and curve properties of the AnimatedContainer to control the animation timing.

By wrapping the ElevatedButton in this AnimatedContainer and using GestureDetector to detect the tap events, we create a smooth elevation animation effect when the button is pressed and released.

Use the Animated ElevatedButtom custom widget

Here’s an example of how to use the AnimatedElevatedButton widget:

import 'AnimatedElevatedButton.dart';
Container(
  alignment: Alignment.topCenter,
  padding: const EdgeInsets.all(8.0),
  child: AnimatedElevatedButton(
    label: 'Elevated Button',
    onPressed: () { print( 'Button pressed!' ); },
  )
),
flutter elevatedbutton elevation animation

The AnimatedElevatedButton widget has two required properties – label and onPressed. The label property is used to specify the text to display within the button and the onPressed property is a callback function that is called when the button is pressed.

When the AnimatedElevatedButton is tapped, it will animate the elevation of the button to create a “pressed” effect, and then call the onPressed callback provided by the parent widget

Flutter ElevatedButton animation with AnimationController

Yes, you can achieve the same effect of animating the elevation of an ElevatedButton using an AnimationController. Here’s how you can do it:

import 'package:flutter/material.dart';

class AnimatedElevatedButton extends StatefulWidget {
  final String label;
  final VoidCallback onPressed;

  const AnimatedElevatedButton({
    Key? key,
    required this.label,
    required this.onPressed,
  }) : super(key: key);

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

class _AnimatedElevatedButtonState extends State<AnimatedElevatedButton> with SingleTickerProviderStateMixin {
  late AnimationController _animationController;
  late Animation<double> _elevationAnimation;

  @override
  void initState() {
    super.initState();
    _animationController = AnimationController(
      vsync: this,
      duration: const Duration(milliseconds: 200),
    );

    _elevationAnimation = Tween<double>(
      begin: 20.0,
      end: 2.0,
    ).animate(CurvedAnimation(
      parent: _animationController,
      curve: Curves.easeInOut,
    ));
  }

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

  @override
  Widget build(BuildContext context) {
    return GestureDetector(
      onTapDown: _onTapDown,
      onTapUp: _onTapUp,
      onTapCancel: _onTapCancel,
      child: AnimatedBuilder(
        animation: _animationController,
        builder: (context, child) {
          return Container(
            decoration: BoxDecoration(
              borderRadius: BorderRadius.circular(8),
              boxShadow: [
                BoxShadow(
                  color: Colors.grey[400]!,
                  offset: Offset(0, _elevationAnimation.value),
                  blurRadius: _elevationAnimation.value,
                ),
              ],
            ),
            child: ElevatedButton(
              onPressed: widget.onPressed,
              child: Text(widget.label),
              style: ElevatedButton.styleFrom(
                elevation: 0,
                shape: RoundedRectangleBorder(
                  borderRadius: BorderRadius.circular(8),
                ),
                padding: EdgeInsets.symmetric(vertical: 10, horizontal: 24),
              ),
            ),
          );
        },
      ),
    );
  }

  void _onTapDown(TapDownDetails details) {
    _animationController.forward();
  }

  void _onTapUp(TapUpDetails details) {
    _animationController.reverse();
    widget.onPressed();
  }

  void _onTapCancel() {
    _animationController.reverse();
  }
}

In this implementation, we create an AnimationController with a duration of 200 milliseconds and an Animation<double> that interpolates between an elevation of 20.0 (the starting value) and 2.0 (the ending value).

We use an AnimatedBuilder to animate the button’s elevation as the _elevationAnimation changes value. We also use the onTapDown, onTapUp, and onTapCancel methods of the GestureDetector to control the animation.

When the user taps down on the button, we call _animationController.forward() to start the animation. When the user lifts their finger from the button or cancels the tap, we call _animationController.reverse() to reverse the animation. When the animation finishes reversing (i.e., the elevation is back to its original value of 20.0), we call the onPressed callback provided by the parent widget.

Note that we use with SingleTickerProviderStateMixin in the widget’s state to provide the vsync parameter for the AnimationController. This parameter is required to synchronize the animation with the widget’s lifecycle.

AnimatedElevatedButton work with different button

If you want to use the same animation effect for other types of buttons in Flutter, you would need to modify the code to work with the specific ButtonStyle used by those buttons. For example, the TextButton widget has a different ButtonStyle than ElevatedButton, so you would need to create a custom animation for the TextButton widget.

However, the general approach of animating a button’s properties to create a visual effect can be applied to any type of button in Flutter. With a bit of modification, you can create custom animations for any type of button to enhance the user experience and create a more engaging interface.

Create a Custom Flutter Button with Animated Background Colour

Creating a custom Flutter button with animated background colour is a great way to add some visual flair to your app. Here’s an example of how to create a custom button with an animated background colour in Flutter:

import 'package:flutter/material.dart';

class AnimatedBackgroundButton extends StatefulWidget {
  final String label;
  final Function onPressed;

  AnimatedBackgroundButton({
    required this.label,
    required this.onPressed,
  });

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

class _AnimatedBackgroundButtonState extends State<AnimatedBackgroundButton>
    with SingleTickerProviderStateMixin {
  late AnimationController _controller;
  late Animation<Color?> _colorAnimation;

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

    _controller = AnimationController(
      vsync: this,
      duration: Duration(milliseconds: 500),
    );

    _colorAnimation = ColorTween(
      begin: Colors.blue,
      end: Colors.red,
    ).animate(_controller);
  }

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

  @override
  Widget build(BuildContext context) {
    return AnimatedBuilder(
      animation: _controller,
      builder: (BuildContext context, Widget? child) {
        return TextButton(
          onPressed: () {
            _controller.forward().then((value) => _controller.reverse());
            widget.onPressed();
          },
          child: Text(widget.label, style: TextStyle(color: Colors.white),),
          style: ButtonStyle(
            backgroundColor: MaterialStateProperty.all(_colorAnimation.value),
          ),
        );
      },
    );
  }
}
flutter button background colour animation

The AnimatedBackgroundButton widget has two required properties – label and onPressed. The label property is used to specify the text to display within the button, and the onPressed property is a callback function that is called when the button is pressed.

The button animates its background colour using a ColorTween and an AnimationController. When the button is pressed, the controller starts the animation, which updates the backgroundColor of the ButtonStyle using an AnimatedBuilder. The animation runs for 500 milliseconds and reverses back to its original state when complete.

To use the AnimatedBackgroundButton widget, simply import the file containing the widget and use it in your code like any other Flutter widget:

import 'AnimatedBackgroundButton.dart';
Container(
alignment: Alignment.topCenter,
padding: const EdgeInsets.all(8.0),
child: AnimatedBackgroundButton(
label: 'Anomated Background Color',
onPressed: () { print( 'Button pressed!' ); },
)
),

Create a Custom Flutter Button with Animated Scale

Here’s an example of how to create a custom Flutter button with an animated button scale:

import 'package:flutter/material.dart';

class AnimatedScaleButton extends StatefulWidget {
final String label;
final Function onPressed;

AnimatedScaleButton({
required this.label,
required this.onPressed,
});

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

class _AnimatedScaleButtonState extends State<AnimatedScaleButton>
with SingleTickerProviderStateMixin {
late AnimationController _controller;
late Animation<double> _animation;

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

_controller = AnimationController(
duration: const Duration(milliseconds: 200),
vsync: this,
);

_animation = Tween<double>(
begin: 1.0,
end: 0.9,
).animate(_controller);
}

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

void _onTapDown(TapDownDetails details) {
_controller.forward();
}

void _onTapUp(TapUpDetails details) {
_controller.reverse();
widget.onPressed();
}

@override
Widget build(BuildContext context) {
return GestureDetector(
onTapDown: _onTapDown,
onTapUp: _onTapUp,
onTapCancel: () {
_controller.reverse();
},
child: ScaleTransition(
scale: _animation,
child: ElevatedButton(
onPressed: () {},
child: Text(widget.label),
style: ElevatedButton.styleFrom(
padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 10),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(20.0),
),
),
),
),
);
}
}
flutter button scale animation

The AnimatedScaleButton widget has two required properties – label and onPressed. The label property is used to specify the text to display within the button and the onPressed property is a callback function that is called when the button is pressed.

The button animates its scale using an AnimationController and a ScaleTransition. The controller is used to manage the animation, which updates the scale factor of the button in response to user input. When the user presses the button, the controller is started, which triggers the ScaleTransition to animate the button’s scale factor.

To use the AnimatedScaleButton widget, simply import the file containing the widget and use it in your code like any other Flutter widget:

import 'AnimatedScaleButton.dart';
Container(
alignment: Alignment.topCenter,
padding: const EdgeInsets.all(8.0),
child: AnimatedScaleButton(
label: 'Anomated Scale',
onPressed: () { print( 'Button pressed!' ); },
)
),

Create a Custom Flutter Button with Animated Border Radius

Here’s an example of how to create a custom Flutter button with an animated button borderRadius:

import 'package:flutter/material.dart';

class AnimatedBorderRadiusButton extends StatefulWidget {
final String label;
final Function onPressed;

AnimatedBorderRadiusButton({
required this.label,
required this.onPressed,
});

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

class _AnimatedBorderRadiusButtonState extends State<AnimatedBorderRadiusButton>
with SingleTickerProviderStateMixin {
late AnimationController _controller;
late Animation<double> _animation;

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

_controller = AnimationController(
duration: const Duration(milliseconds: 200),
vsync: this,
);

_animation = Tween<double>(
begin: 0.0,
end: 20.0,
).animate(_controller);
}

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

void _onTapDown(TapDownDetails details) {
_controller.forward();
}

void _onTapUp(TapUpDetails details) {
_controller.reverse();
widget.onPressed();
}

@override
Widget build(BuildContext context) {
return GestureDetector(
onTapDown: _onTapDown,
onTapUp: _onTapUp,
onTapCancel: () {
_controller.reverse();
},
child: AnimatedBuilder(
animation: _controller,
builder: (BuildContext context, Widget? child) {
return ElevatedButton(
onPressed: () {},
child: Text(widget.label),
style: ElevatedButton.styleFrom(
padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 10),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(_animation.value),
),
),
);
},
),
);
}
}
flutter button border radius animation

The AnimatedBorderRadiusButton widget has two required properties – label and onPressed. The label property is used to specify the text to display within the button, and the onPressed property is a callback function that is called when the button is pressed.

The button animates its borderRadius using an AnimationController and an AnimatedBuilder. The controller is used to manage the animation, which updates the borderRadius value of the buttons ShapeBorder in response to user input. When the user presses the button, the controller is started, which triggers the AnimatedBuilder to rebuild the button with a new borderRadius value based on the current value of the animation.

To use the AnimatedBorderRadiusButton widget, simply import the file containing the widget and use it in your code like any other Flutter widget:

import 'AnimatedBorderRadiusButton.dart';
Container(
alignment: Alignment.topCenter,
padding: const EdgeInsets.all(8.0),
child: AnimatedBorderRadiusButton(
label: 'Anomated Border Radius',
onPressed: () { print( 'Button pressed!' ); },
)
),

Create a Custom Flutter Button with Animated Foreground Colour

To create a custom Flutter button with an animated foreground colour, you can use an AnimatedDefaultTextStyle widget. This widget animates between two TextStyle objects, allowing you to change the foreground colour of the text when the button is pressed.

Here’s an example code that shows how to create a custom button with an animated foreground colour:

import 'package:flutter/material.dart';

class AnimatedColorButton extends StatefulWidget {
  final String label;
  final VoidCallback onPressed;

  AnimatedColorButton({required this.label, required this.onPressed});

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

class _AnimatedColorButtonState extends State<AnimatedColorButton> {
  Color _color = Colors.blue;
  FontWeight _fontWeight = FontWeight.normal;

  @override
  Widget build(BuildContext context) {
    return GestureDetector(
      onTapDown: (details) {
        setState(() {
          _color = Colors.red;
          _fontWeight = FontWeight.bold;
        });
      },
      onTapUp: (details) {
        setState(() {
          _color = Colors.blue;
          _fontWeight = FontWeight.normal;
        });
        widget.onPressed();
      },
      child: AnimatedDefaultTextStyle(
        style: TextStyle(
          color: _color,
          fontWeight: _fontWeight,
        ),
        duration: Duration(milliseconds: 200),
        child: Container(
          decoration: BoxDecoration(
            color: Colors.white,
            borderRadius: BorderRadius.circular(10),
            boxShadow: [
              BoxShadow(
                color: Colors.grey.withOpacity(0.5),
                spreadRadius: 2,
                blurRadius: 5,
                offset: Offset(0, 3),
              ),
            ],
          ),
          padding: EdgeInsets.symmetric(vertical: 10, horizontal: 20),
          child: Text(
            widget.label,
          ),
        ),
      ),
    );
  }
}
flutter button text colour animation

In this example, we use a GestureDetector to detect taps on the button. When the user taps down, we update the state to change the colour and font weight of the text, and when the user releases the tap, we update the state again to reset the colour and font weight, and also call the onPressed callback.

The button is wrapped in an AnimatedDefaultTextStyle widget, which animates between two text styles based on the state. The duration parameter controls the speed of the animation.

Note that we also added a simple box shadow to the button to give it a bit of depth.

Here is how to use the button:

import 'AnimatedColorButton.dart';
Container(
alignment: Alignment.topCenter,
padding: const EdgeInsets.all(8.0),
child: AnimatedColorButton(
label: 'Anomated Text Colour',
onPressed: () { print( 'Button pressed!' ); },
)
),