Open In App

AnimatedWidget flutter

Last Updated : 08 Jul, 2024
Comments
Improve
Suggest changes
Like Article
Like
Report

In Flutter, creating these visually attractive and smooth Animations can be a challenging task, as everything in Flutter is a Widget, and would need strong control over the widget state and transitions. For that, we have the "AnimatedWidget" class in Flutter.

What is AnimatedWidget in Flutter?

'AnimatedWidget' is a powerful class in Flutter's animation framework, that is used to simplify the implementation of animations in Mobile Apps. They are used with Animation objects, which are Listenable, although they can be used with any listenable including Value Notifier and ChangeNotifier. AnimatedWidget is particularly valuable for stateless widgets that need animation capabilities. By using this, developers can create dynamic and responsive UI elements that respond when the user interacts with it, in real-time; improving the aesthetic appeal of the app but also providing a enjoyable and fun experience.

Understanding 'AnimatedWidget' Class

The AnimatedWidget isn't exactly a widget but an abstract class, but it is a powerful tool from which we can create our own animations. There are some built-in animated widgets already built for you like SizeTransition, RotationTransistion, ButtonTransition etc. We can also make our own custom animations if we want.

Steps to Build Custom AnimatedWidget in Flutter

Step 1: Set Up Your Flutter Project

Create a new Flutter project:

animatedwidget_01


Step 2 : Create the Main App

Create the main entry point for your Flutter application :

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

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'AnimatedWidget Example',
      theme: ThemeData(
        primarySwatch: Colors.green,
      ),
      home: MyHomePage(),
    );
  }
}


Step 3: Create the AnimatedWidget

Create a custom AnimatedWidget to handle the color animation.

Dart
class ColorTransition extends AnimatedWidget {
  ColorTransition({Key? key, required Animation<Color?> animation})
      : super(key: key, listenable: animation);

  @override
  Widget build(BuildContext context) {
    final animation = listenable as Animation<Color?>;
    return Container(
      height: 100,
      width: 100,
      color: animation.value,
    );
  }
}


Step 4: Implement the Home Page with Animation

Implement the MyHomePage widget to control the animation and handle the button click.

Dart
class MyHomePage extends StatefulWidget {
  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> with SingleTickerProviderStateMixin {
  late AnimationController _controller;
  late Animation<Color?> _animation;
  bool _isAnimating = false;

  @override
  void initState() {
    super.initState();
    _controller = AnimationController(
      duration: const Duration(seconds: 1),
      vsync: this,
    );
    _animation = ColorTween(begin: Colors.green, end: Colors.blue).animate(_controller);
  }

  void _handleClick() {
    if (_isAnimating) {
      _controller.reverse();
    } else {
      _controller.forward();
    }
    _isAnimating = !_isAnimating;
  }

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('GeeksForGeeks Animations'),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            ColorTransition(animation: _animation),
            SizedBox(height: 20),
            ElevatedButton(
              onPressed: _handleClick,
              child: Text('Click Me'),
            ),
          ],
        ),
      ),
    );
  }
}


Here's the Complete Code of the AnimatedWidget Example :

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

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'AnimatedWidget Example',
      theme: ThemeData(
        primarySwatch: Colors.green,
      ),
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatefulWidget {
  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> with SingleTickerProviderStateMixin {
  late AnimationController _controller;
  late Animation<Color?> _animation;
  bool _isAnimating = false;

  @override
  void initState() {
    super.initState();
    _controller = AnimationController(
      duration: const Duration(seconds: 1),
      vsync: this,
    );
    _animation = ColorTween(begin: Colors.green, end: Colors.blue).animate(_controller);
  }

  void _handleClick() {
    if (_isAnimating) {
      _controller.reverse();
    } else {
      _controller.forward();
    }
    _isAnimating = !_isAnimating;
  }

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('GeeksForGeeks Animations'),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            ColorTransition(animation: _animation),
            SizedBox(height: 20),
            ElevatedButton(
              onPressed: _handleClick,
              child: Text('Click Me'),
            ),
          ],
        ),
      ),
    );
  }
}

class ColorTransition extends AnimatedWidget {
  ColorTransition({Key? key, required Animation<Color?> animation})
      : super(key: key, listenable: animation);

  @override
  Widget build(BuildContext context) {
    final animation = listenable as Animation<Color?>;
    return Container(
      height: 100,
      width: 100,
      color: animation.value,
    );
  }
}


And when we click the Click Me button, the container color will change to blue and back to green creating a simple but effective color animation.

Output :


Now let's add into this color transition and also increase the size in the next animation example

Example 2 of AnimatedWidget

Let's create another simple example where a "Click Me" button triggers an animation of a container changing both its color and size as well

1. Importing Packages

First, we import the necessary Flutter material package:

import 'package:flutter/material.dart';

2. Create the Main app

Add the main entry point for your Flutter application:

Dart
void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Animated Widgets',
      theme: ThemeData(primarySwatch: Colors.blue),
      home: const MyHomePage(),
    );
  }
}


3. Setup the Animation:

Configuring color and size of animations for MyHomePage widget :

Dart
class _MyHomePageState extends State<MyHomePage> with SingleTickerProviderStateMixin {
  late AnimationController _controller;
  late Animation<Color?> _colorAnimation;
  late Animation<double> _sizeAnimation;

  @override
  void initState() {
    super.initState();
    _controller = AnimationController(
      duration: const Duration(seconds: 1),
      vsync: this,
    );
    _colorAnimation = ColorTween(begin: Colors.green, end: Colors.blue).animate(_controller);
    _sizeAnimation = Tween<double>(begin: 100, end: 200).animate(_controller);
  }

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

  void _startAnimation() {
    if (_controller.status == AnimationStatus.completed) {
      _controller.reverse();
    } else {
      _controller.forward();
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text("Animated Widget Example"),
        centerTitle: true,
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            AnimatedBuilder(
              animation: _controller,
              builder: (context, child) {
                return Container(
                  height: _sizeAnimation.value,
                  width: _sizeAnimation.value,
                  color: _colorAnimation.value,
                );
              },
            ),
            ElevatedButton(
              onPressed: _startAnimation,
              child: const Text("Click Me"),
            ),
          ],
        ),
      ),
    );
  }
}


4. Implement the HomePage with Animations

Configuring color and size animations with “HomePage” widget

Dart
class MyHomePage extends StatefulWidget {
  const MyHomePage({Key? key}) : super(key: key);

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> with SingleTickerProviderStateMixin {
  late AnimationController _controller;
  late Animation<Color?> _colorAnimation;
  late Animation<double> _sizeAnimation;

  @override
  void initState() {
    super.initState();
    _controller = AnimationController(
      duration: const Duration(seconds: 1),
      vsync: this,
    );
    _colorAnimation = ColorTween(begin: Colors.green, end: Colors.blue).animate(_controller);
    _sizeAnimation = Tween<double>(begin: 100, end: 200).animate(_controller);
  }

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

  void _startAnimation() {
    if (_controller.status == AnimationStatus.completed) {
      _controller.reverse();
    } else {
      _controller.forward();
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text("Animated Widget Example"),
        centerTitle: true,
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            AnimatedBuilder(
              animation: _controller,
              builder: (context, child) {
                return Container(
                  height: _sizeAnimation.value,
                  width: _sizeAnimation.value,
                  color: _colorAnimation.value,
                );
              },
            ),
            ElevatedButton(
              onPressed: _startAnimation,
              child: const Text("Click Me"),
            ),
          ],
        ),
      ),
    );
  }
}


Here's the Full code of AnimatedWidget Example :

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

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'GeeksforGeeks AnimatedWidget Example',
      theme: ThemeData(
        primarySwatch: Colors.green,
      ),
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatefulWidget {
  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> with SingleTickerProviderStateMixin {
  late AnimationController _controller;
  late Animation<double> _animation;

  @override
  void initState() {
    super.initState();
    _controller = AnimationController(
      duration: const Duration(seconds: 2),
      vsync: this,
    );
    _animation = Tween<double>(begin: 100, end: 200).animate(_controller);
  }

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

  void _startAnimation() {
    if (_controller.isAnimating) {
      _controller.reverse();
    } else {
      _controller.forward();
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('GeeksforGeeks Animations'),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            ColorSizeAnimation(animation: _animation),
            SizedBox(height: 20),
            ElevatedButton(
              onPressed: _startAnimation,
              child: Text('Click Me'),
            ),
          ],
        ),
      ),
    );
  }
}

class ColorSizeAnimation extends AnimatedWidget {
  ColorSizeAnimation({Key? key, required Animation<double> animation})
      : super(key: key, listenable: animation);

  @override
  Widget build(BuildContext context) {
    final animation = listenable as Animation<double>;
    return Container(
      height: animation.value,
      width: animation.value,
      color: Color.lerp(Colors.green, Colors.blue, animation.value / 200),
    );
  }
}


When you run the above code, you will see a green container in the center of the screen. When you click the "Click Me" button, the container will smoothly transition in size and color, creating an engaging and dynamic animation.

Output:



Next Article

Similar Reads