0
0
Fluttermobile~20 mins

AnimationController in Flutter - Mini App: Build & Ship

Choose your learning style9 modes available
Build: Simple Animation Screen
This screen shows a square that grows and shrinks continuously using AnimationController.
Target UI
┌─────────────────────────────┐
│ Simple Animation Screen      │
│                             │
│          ■■■■■■■■           │
│          ■      ■           │
│          ■      ■           │
│          ■■■■■■■■           │
│                             │
│  [Start Animation] [Stop]   │
└─────────────────────────────┘
Add a square container that changes size smoothly from small to large repeatedly.
Use AnimationController to control the animation.
Add two buttons: 'Start Animation' to begin the animation and 'Stop' to stop it.
The animation should loop back and forth (grow then shrink).
Starter Code
Flutter
import 'package:flutter/material.dart';

class SimpleAnimationScreen extends StatefulWidget {
  @override
  State<SimpleAnimationScreen> createState() => _SimpleAnimationScreenState();
}

class _SimpleAnimationScreenState extends State<SimpleAnimationScreen> with SingleTickerProviderStateMixin {
  late AnimationController _controller;

  @override
  void initState() {
    super.initState();
    _controller = AnimationController(
      vsync: this,
      duration: const Duration(seconds: 2),
    );
    // TODO: Add animation behavior here
  }

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Simple Animation Screen')),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            // TODO: Add animated square here
            const SizedBox(height: 40),
            Row(
              mainAxisAlignment: MainAxisAlignment.center,
              children: [
                ElevatedButton(
                  onPressed: () {
                    // TODO: Start animation
                  },
                  child: const Text('Start Animation'),
                ),
                const SizedBox(width: 20),
                ElevatedButton(
                  onPressed: () {
                    // TODO: Stop animation
                  },
                  child: const Text('Stop'),
                ),
              ],
            ),
          ],
        ),
      ),
    );
  }
}
Task 1
Task 2
Task 3
Task 4
Solution
Flutter
import 'package:flutter/material.dart';

class SimpleAnimationScreen extends StatefulWidget {
  @override
  State<SimpleAnimationScreen> createState() => _SimpleAnimationScreenState();
}

class _SimpleAnimationScreenState extends State<SimpleAnimationScreen> with SingleTickerProviderStateMixin {
  late AnimationController _controller;
  late Animation<double> _sizeAnimation;

  @override
  void initState() {
    super.initState();
    _controller = AnimationController(
      vsync: this,
      duration: const Duration(seconds: 2),
    );

    _sizeAnimation = Tween<double>(begin: 100, end: 200).animate(_controller);

    _controller.addStatusListener((status) {
      if (status == AnimationStatus.completed) {
        _controller.reverse();
      } else if (status == AnimationStatus.dismissed) {
        _controller.forward();
      }
    });
  }

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Simple Animation Screen')),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            AnimatedBuilder(
              animation: _sizeAnimation,
              builder: (context, child) {
                return Container(
                  width: _sizeAnimation.value,
                  height: _sizeAnimation.value,
                  color: Colors.blue,
                );
              },
            ),
            const SizedBox(height: 40),
            Row(
              mainAxisAlignment: MainAxisAlignment.center,
              children: [
                ElevatedButton(
                  onPressed: () {
                    _controller.forward();
                  },
                  child: const Text('Start Animation'),
                ),
                const SizedBox(width: 20),
                ElevatedButton(
                  onPressed: () {
                    _controller.stop();
                  },
                  child: const Text('Stop'),
                ),
              ],
            ),
          ],
        ),
      ),
    );
  }
}

We use AnimationController to control the animation timing. The controller runs for 2 seconds. We create a Tween that changes the size from 100 to 200 pixels. The AnimatedBuilder rebuilds the square container whenever the animation value changes, updating its width and height.

We listen to the animation status to make it reverse direction when it finishes growing, and forward again when it finishes shrinking. This creates a smooth back-and-forth effect.

The 'Start Animation' button calls _controller.forward() to begin the animation. The 'Stop' button calls _controller.stop() to pause it.

This example shows how to use AnimationController simply and clearly to animate a widget's size.

Final Result
Completed Screen
┌─────────────────────────────┐
│ Simple Animation Screen      │
│                             │
│          ■■■■■■■■■■■■■■     │
│          ■            ■     │
│          ■            ■     │
│          ■■■■■■■■■■■■■■     │
│                             │
│  [Start Animation] [Stop]   │
└─────────────────────────────┘
When user taps 'Start Animation', the blue square smoothly grows from 100x100 to 200x200 pixels and then shrinks back repeatedly.
When user taps 'Stop', the animation pauses and the square stays at its current size.
Stretch Goal
Add a slider to control the animation speed dynamically.
💡 Hint
Use the slider's value to update the AnimationController's duration and restart the animation.