Implicit Animations

Easy automatic animations in Flutter

⚡ What are Implicit Animations?

Implicit animations are Flutter's easiest way to animate widgets. They automatically animate property changes without manual control, using built-in animated widgets like AnimatedContainer, AnimatedOpacity, and AnimatedPadding for smooth transitions effortlessly.


// Automatically animates when color changes
AnimatedContainer(
  duration: Duration(seconds: 1),
  color: isBlue ? Colors.blue : Colors.red,
)
                                    

Common Implicit Animation Widgets

📦

AnimatedContainer

Animates size, color, padding, and more

Size Color Padding
👁️

AnimatedOpacity

Fade in and out effects

Fade In Fade Out Visibility
📍

AnimatedPositioned

Smooth position changes in Stack

Top Left Right
🔄

AnimatedRotation

Rotate widgets smoothly

Spin Rotate Turn

🔹 AnimatedContainer Example

The most versatile implicit animation widget:

class AnimatedBox extends StatefulWidget {
  @override
  _AnimatedBoxState createState() => _AnimatedBoxState();
}

class _AnimatedBoxState extends State {
  bool isExpanded = false;

  @override
  Widget build(BuildContext context) {
    return GestureDetector(
      onTap: () {
        setState(() {
          isExpanded = !isExpanded;
        });
      },
      child: AnimatedContainer(
        duration: Duration(milliseconds: 500),
        curve: Curves.easeInOut,
        width: isExpanded ? 300 : 100,
        height: isExpanded ? 300 : 100,
        decoration: BoxDecoration(
          color: isExpanded ? Colors.blue : Colors.red,
          borderRadius: BorderRadius.circular(
            isExpanded ? 50 : 10
          ),
        ),
        child: Center(
          child: Text(
            'Tap Me',
            style: TextStyle(
              color: Colors.white,
              fontSize: isExpanded ? 24 : 16,
            ),
          ),
        ),
      ),
    );
  }
}

🔹 AnimatedOpacity Example

Create smooth fade effects:

class FadeInWidget extends StatefulWidget {
  @override
  _FadeInWidgetState createState() => _FadeInWidgetState();
}

class _FadeInWidgetState extends State {
  bool isVisible = true;

  @override
  Widget build(BuildContext context) {
    return Column(
      children: [
        AnimatedOpacity(
          opacity: isVisible ? 1.0 : 0.0,
          duration: Duration(milliseconds: 800),
          child: Container(
            width: 200,
            height: 200,
            color: Colors.green,
            child: Center(
              child: Text(
                'Hello!',
                style: TextStyle(
                  color: Colors.white,
                  fontSize: 24,
                ),
              ),
            ),
          ),
        ),
        SizedBox(height: 20),
        ElevatedButton(
          onPressed: () {
            setState(() {
              isVisible = !isVisible;
            });
          },
          child: Text('Toggle Visibility'),
        ),
      ],
    );
  }
}

🔹 AnimatedPositioned Example

Move widgets smoothly within a Stack:

class MovingBox extends StatefulWidget {
  @override
  _MovingBoxState createState() => _MovingBoxState();
}

class _MovingBoxState extends State {
  bool isMoved = false;

  @override
  Widget build(BuildContext context) {
    return Stack(
      children: [
        AnimatedPositioned(
          duration: Duration(seconds: 1),
          curve: Curves.bounceOut,
          top: isMoved ? 200 : 50,
          left: isMoved ? 200 : 50,
          child: GestureDetector(
            onTap: () {
              setState(() {
                isMoved = !isMoved;
              });
            },
            child: Container(
              width: 100,
              height: 100,
              color: Colors.purple,
              child: Center(
                child: Icon(
                  Icons.touch_app,
                  color: Colors.white,
                ),
              ),
            ),
          ),
        ),
      ],
    );
  }
}

🔹 AnimatedPadding Example

Animate spacing changes:

class PaddingAnimation extends StatefulWidget {
  @override
  _PaddingAnimationState createState() => _PaddingAnimationState();
}

class _PaddingAnimationState extends State {
  bool hasPadding = false;

  @override
  Widget build(BuildContext context) {
    return GestureDetector(
      onTap: () {
        setState(() {
          hasPadding = !hasPadding;
        });
      },
      child: Container(
        color: Colors.grey[200],
        child: AnimatedPadding(
          duration: Duration(milliseconds: 600),
          padding: EdgeInsets.all(hasPadding ? 50.0 : 10.0),
          child: Container(
            color: Colors.orange,
            child: Center(
              child: Text('Tap to change padding'),
            ),
          ),
        ),
      ),
    );
  }
}

🔹 AnimatedRotation Example

Rotate widgets with ease:

class RotatingIcon extends StatefulWidget {
  @override
  _RotatingIconState createState() => _RotatingIconState();
}

class _RotatingIconState extends State {
  double turns = 0.0;

  @override
  Widget build(BuildContext context) {
    return Column(
      mainAxisAlignment: MainAxisAlignment.center,
      children: [
        AnimatedRotation(
          turns: turns,
          duration: Duration(milliseconds: 500),
          child: Icon(
            Icons.refresh,
            size: 100,
            color: Colors.blue,
          ),
        ),
        SizedBox(height: 20),
        ElevatedButton(
          onPressed: () {
            setState(() {
              turns += 0.25; // Rotate 90 degrees
            });
          },
          child: Text('Rotate'),
        ),
      ],
    );
  }
}

🔹 Combining Multiple Animations

Use multiple implicit animations together:

class CombinedAnimation extends StatefulWidget {
  @override
  _CombinedAnimationState createState() => _CombinedAnimationState();
}

class _CombinedAnimationState extends State {
  bool isActive = false;

  @override
  Widget build(BuildContext context) {
    return GestureDetector(
      onTap: () {
        setState(() {
          isActive = !isActive;
        });
      },
      child: AnimatedContainer(
        duration: Duration(milliseconds: 700),
        curve: Curves.easeInOut,
        width: isActive ? 250 : 150,
        height: isActive ? 250 : 150,
        decoration: BoxDecoration(
          color: isActive ? Colors.teal : Colors.amber,
          borderRadius: BorderRadius.circular(isActive ? 125 : 20),
          boxShadow: [
            BoxShadow(
              color: Colors.black26,
              blurRadius: isActive ? 20 : 5,
              offset: Offset(0, isActive ? 10 : 5),
            ),
          ],
        ),
        child: AnimatedOpacity(
          opacity: isActive ? 1.0 : 0.5,
          duration: Duration(milliseconds: 700),
          child: Center(
            child: Icon(
              isActive ? Icons.star : Icons.star_border,
              size: isActive ? 80 : 50,
              color: Colors.white,
            ),
          ),
        ),
      ),
    );
  }
}

💡 Implicit Animation Tips:

  • Duration: Keep animations between 200-800ms for best UX
  • Curves: Use Curves.easeInOut for natural motion
  • Performance: Implicit animations are optimized by Flutter
  • setState: Always call setState() to trigger animations
  • Simplicity: Use implicit animations for simple property changes

🧠 Test Your Knowledge

Which widget would you use to animate opacity changes?