How to Create Custom Animations in Flutter – A Step-by-Step Guide

How to Create Custom Animations in Flutter – A Step-by-Step Guide

In the world of mobile app development, animations are essential for developing creative, engaging and visually appealing mobile apps. In Flutter, Google’s open-source UI software development kit is the most reliable, powerful and robust framework for custom application development. This eye-catching, responsive, and visually appealing animation is made only possible with the Flutter app development, if you want to add the subtle transitions in your business project.

In this blog, we will go through a step-by-step process of custom animations development in Flutter. We will also represent the most crucial concepts and the Flutter animation framework and deliver the coding examples that will support you to get started.

Why Use Custom Animation in Flutter Development?

In the app development process animation will help you to boost the user experience, give feedback, and make your app responsive and dynamic for your business. However, custom animation is most significant when the standard widgets and transitions do not meet your project’s design requirements and demands. If you wish to build a custom animation, then, you need to have full control over how your UI elements are transmitted, faded, or transformed in your app or project. Therefore, it also delivers a unique user experience for your application.

Which are the Most Significant Flutter Animation Concept?s

Let’s see some of the basic or key animation concepts in Flutter app development, before moving forward with the code example.

Tween: In this animation, it is essential to describe a wide range of values between which an animation should interpolate. For instance, you can develop the usage of the Tween to know the beginning and ending values for an animation in the app.

Controller: An Animation Controller is responsible for managing and controlling the animation state. It will automatically handle the animation playback, duration, and will operate forward or backward in your business project.

Animation: The Flutter app will represent the updated or modified value over time. It can be simple, such as modifying the opacity or the complexity of a full-page transition.

Benefits of Android App Development For Your Business in 2024

What is the Flutter Animation Framework?

Flutter provides a robust and reliable animation framework that eases the development of animations. Let’s have a look at some of the essential components of the Flutter app’s framework:

1. Animation Controller

It controls the timing and playback of an animation in your Flutter app. It allows the user to describe a duration, curve, and animation loop or reverse. Let’s see a simple example of creating an AnimationController.

dart

AnimationController controller = AnimationController(

  duration: Duration(seconds: 2),

  vsync: this, // TickerProvider (e.g., State or TickerProviderStateMixin)

);

2. Tween Animation

It defines a range of values that an animation should interpolate between. If you want to animate a widget position from one point to another, use a Tween<Offset> in your example.

dart

Animation<Offset> positionAnimation = Tween<Offset>(

  begin: Offset(0, 0),

  end: Offset(100, 100),

).animate(controller);

3. AnimatedBuilder

It is a handy tool for creating widgets that are based on animation. It also allows you to rebuild a part of your UI tree whenever the animation value changes. Let’s have a look at a simple example of how to use AnimatedBuilder:

dart

AnimatedBuilder(

  animation: positionAnimation,

  builder: (context, child) {

    return Positioned(

      left: positionAnimation.value.dx,

      top: positionAnimation.value.dy,

      child: child,

    );

  },

  child: MyWidget(),

)

Developing Custom Animations

Here, we have covered the basics of the Flutter animation framework. Let’s create some custom animations.

Simple Opacity Animation

In this example, fade a widget in and out using an opacity animation. In this scenario, we will use a Tween<double> for interpolating the opacity value.

dart

class OpacityAnimationExample extends StatefulWidget {

  @override

  _OpacityAnimationExampleState createState() => _OpacityAnimationExampleState();

}

class _OpacityAnimationExampleState extends State<OpacityAnimationExample> with SingleTickerProviderStateMixin {

  late AnimationController controller;

  late Animation<double> opacityAnimation;


  @override

  void initState() {

    super.initState();

    controller = AnimationController(

      duration: Duration(seconds: 2),

      vsync: this,

    );

    opacityAnimation = Tween<double>(

      begin: 0.0,

      end: 1.0,

    ).animate(controller);

    controller.forward(); // Start the animation

  }


  @override

  void dispose() {

    controller.dispose(); // Clean up the controller

    super.dispose();

  }

  @override

  Widget build(BuildContext context) {

    return Center(

      child: AnimatedBuilder(

        animation: opacityAnimation,

        builder: (context, child) {

          return Opacity(

            opacity: opacityAnimation.value,

            child: Container(

              width: 200,

              height: 200,

              color: Colors.blue,

            ),

          );

        },

      ),

    );

  }

}

In this illustration, we have created an opacity animation that begins at 0.0 and ends at 1.0, making a blue container fade in. The ‘AnimatedBuilder’ Widget will rebuild a container whenever the animation value changes.

Animating Widget Properties

Flutter can animate widget properties like size, rotation, and position. Let’s look at how to animate the widget position using the transform widget.

dart

class PositionAnimationExample extends StatefulWidget {

  @override

  _PositionAnimationExampleState createState() => _PositionAnimationExampleState();

}

class _PositionAnimationExampleState extends State<PositionAnimationExample> with SingleTickerProviderStateMixin {

  late AnimationController controller;

  late Animation<Offset> positionAnimation;


  @override

  void initState() {

    super.initState();

    controller = AnimationController(

      duration: Duration(seconds: 2),

      vsync: this,

    );

    positionAnimation = Tween<Offset>(

      begin: Offset(0, 0),

      end: Offset(100, 100),

    ).animate(controller);

    controller.forward(); // Start the animation

  }

  @override

  void dispose() {

    controller.dispose(); // Clean up the controller

    super.dispose();

  }

  @override

  Widget build(BuildContext context) {

    return Center(

      child: AnimatedBuilder(

        animation: positionAnimation,

        builder: (context, child) {

          return Transform.translate(

            offset: positionAnimation.value,

            child: Container(

              width: 100,

              height: 100,

              color: Colors.red,

            ),

          );

        },

      ),

    );

  }

}

In this example, we use a ‘Transform.translate’ widget to forward the red container from its initial position to a new position defined by the ‘positionAnimation’.

Complex Custom Animation

Custom complex animation can get complicated with imagination. You can combine various animations, use different curves, and develop innovative animation that will match your application’s design. Let’s see a simple example of a complex custom animation.

dart

class ComplexAnimationExample extends StatefulWidget {

  @override

  _ComplexAnimationExampleState createState() => _ComplexAnimationExampleState();

}

class _ComplexAnimationExampleState extends State<ComplexAnimationExample> with SingleTickerProviderStateMixin {

  late AnimationController controller;

  late Animation<Offset> positionAnimation;

  late Animation<double> opacityAnimation;

 @override

  void initState() {

    super.initState();

    controller = AnimationController(

      duration: Duration(seconds: 2),

      vsync: this,

    );

    positionAnimation = Tween<Offset>(

      begin: Offset(0, 0),

      end: Offset(100, 100),

    ).animate(CurvedAnimation(

      parent: controller,

      curve: Curves.easeInOut,

    ));

    opacityAnimation = Tween<double>(

      begin: 0.0,

      end: 1.0,

    ).animate(controller);

    controller.forward(); // Start the animation

  }

@override

  void dispose() {

    controller.dispose(); // Clean up the controller

    super.dispose();

  }

 @override

  Widget build(BuildContext context) {

    return Center(

      child: AnimatedBuilder(

        animation: controller,

        builder: (context, child) {

          return Transform.translate(

            offset: positionAnimation.value,

            child: Opacity(

              opacity: opacityAnimation.value,

              child: Container(

                width: 150,

                height: 150,

                color: Colors.green,

              ),

            ),

          );

        },

      ),

    );

  }

}

In this example, we have merged the position and opacity animation to develop a more intricate animation effect.

Gestures and Interactivity

Developing animations that respond to user interaction is the most essential aspect of mobile app development. In Flutter, implementing the interactivity to your custom animations is easy.

Trigger Animations

You can trigger an animation according to the user’s action by pressing a button or making gestures. For instance, to animate the widget, a button is clicked, and for that, you can make the utilization of the following code:

dart
GestureDetector(
  onTap: () {
    controller.forward(); // Start the animation
  },
  child: MyButtonWidget(),
)

Gesture-Based Animation

Flutter delivers multiple gestures, such as GestureDetector and Draggable. GestureDetector is used to make interactive animations. Here, we will build a draggable widget that is animated when it is dragged into the project or in application.

dart
class DraggableAnimationExample extends StatefulWidget {
  @override
  _DraggableAnimationExampleState createState() => _DraggableAnimationExampleState();
}

class _DraggableAnimationExampleState extends State<DraggableAnimationExample> {
  late AnimationController controller;
  late Animation<Offset> positionAnimation;

  @override
  void initState() {
    super.initState();
    controller = AnimationController(
      duration: Duration(seconds: 1),
      vsync: this,
    );
    positionAnimation = Tween<Offset>(
      begin: Offset(0, 0),
      end: Offset(0, 100),
    ).animate(controller);
  }

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

  @override
  Widget build(BuildContext context) {
    return Center(
      child: GestureDetector(
        onVerticalDragUpdate: (details) {
          // Update the animation value based on drag
          controller.value -= details.primaryDelta! / 100.0;
        },
        onVerticalDragEnd: (details) {
          // Determine whether to complete or reverse the animation
          if (details.velocity.pixelsPerSecond.dy > 200) {
            controller.reverse();
          } else {
            controller.forward();
          }
        },
        child: AnimatedBuilder(
          animation: controller,
          builder: (context, child) {
            return Transform.translate(
              offset: positionAnimation.value,
              child: Container(
                width: 100,
                height: 100,
                color: Colors.orange,
              ),
            );
          },
        ),
      ),
    );
  }
}

In the above-described example, the widget can be vertically dragged up or down, and the animation will respond to drag gestures. The onVerticalDragUpdate and onVerticalDragEnd callbacks will control or manage the animation based on user actions or input.

Optimizing Animations

Animation optimization is crucial to get smooth performance in your Flutter app. Below are some tips that support you to enhance the animation performance.

Performance Consideration

Minimize Rebuild Area: Use an AnimatedBuilder Widget or the same techniques to rebuild only the UI components based on animation. This will reduce the number of widgets that need to be rebuilt and will also improve performance.

Leverage const Constructors: Utilize a const constructor for your widget to decrease the widget tree modification during the animations.

Ignore Huge Use of Widgets: In the UI tree, you should limit the widgets, particularly when the animation has a complex or difficult layout. Also, a deep widget tree can slow down the animations.

Use AnimatedOpacity and AnimatedContainer

Flutter gives particular widgets, such as AnimatedContainer and AnimatedOpacity, which will create a simple standard animation by managing the underlying animation logic for you. These widgets will automatically animate changes to their properties, like size and opacity.

dart
AnimatedContainer(
  duration: Duration(seconds: 1),
  width: _isExpanded ? 200.0 : 50.0,
  height: _isExpanded ? 200.0 : 50.0,
  color: _isExpanded ? Colors.blue : Colors.red,
)

In this above-described example, container size and colors are animated smoothly and easily when the _isExapnded changes.

Hero Animations

If you need a seamless transition between multiple screens, you must consider using Hero animations. These animations smoothly interpolate the transition of widgets from one screen to another and develop visually pleasing effects while navigating between the different parts of your application.

Animation Built Using External Tools

Another way to add new value to your mobile app is to use one of our external tools, Flutter, in your project. Flutter creates an animation that is exported in the Flutter app. Let’s have a look.

Adobe After Effects

It is the most popular animation and visual effect software, which permits you to make complex animations. The plugin known as Lottie exports it in various formats.

Sketch

An app designer most likes a vector graphic editor. It uses a plugin, Sketch2Flutter, that allows the developer to export design and animation.

Figma

A plugin known as Flutter will interact with export designs and animations and Flutter coding. Thus, this code is used to develop the animation directly inside your Flutter application.

Conclusion

Creating custom animation in Flutter permits you to integrate the touch of creativity and interactivity into your mobile application. The Flutter animation framework gives flexibility and reliability. It provides a creative app user interface that captivates and engages your users. 

Firstly, you must begin with the basics and understand the significant animation concepts and the Flutter animation framework. Simple animations are possible with complicated animations and are most trustworthy with the framework. Flutter focuses on performance and developer productivity, which makes it a superb choice for creating animations that are not visually appealing. It is also responsive and smooth. If you want to create a delightful user experience in the custom application, hire Flutter developer to simplify your complex animation. Happy Coding!

Connect with Experts Now!

Request a Quote