Obafemi Emmanuel

Flutter Animations & UI Enhancements

Published 3 months ago

Flutter provides a powerful animation framework that enables developers to create smooth and visually appealing user interfaces. In this blog, we will explore various animation techniques, including implicit and explicit animations, Hero animation, Lottie animations, custom animations with AnimatedBuilder, and page transitions.


8.1 Implicit & Explicit Animations

Flutter animations are broadly classified into two types:


Implicit Animations

Implicit animations are easy to implement as they handle animation management automatically. They animate changes in properties over a specified duration.

Example: AnimatedContainer

import 'package:flutter/material.dart';

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

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  bool _isExpanded = false;

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(title: Text("Implicit Animation")),
        body: Center(
          child: GestureDetector(
            onTap: () {
              setState(() {
                _isExpanded = !_isExpanded;
              });
            },
            child: AnimatedContainer(
              duration: Duration(seconds: 1),
              width: _isExpanded ? 200 : 100,
              height: _isExpanded ? 200 : 100,
              color: _isExpanded ? Colors.blue : Colors.red,
              alignment: Alignment.center,
              child: Text("Tap Me", style: TextStyle(color: Colors.white)),
            ),
          ),
        ),
      ),
    );
  }
}

Explicit Animations

Explicit animations give more control but require managing animations manually using AnimationController.


Example: Tween Animation

import 'package:flutter/material.dart';

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

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> with SingleTickerProviderStateMixin {
  late AnimationController _controller;
  late Animation<double> _animation;

  @override
  void initState() {
    super.initState();
    _controller = AnimationController(
      duration: Duration(seconds: 2),
      vsync: this,
    )..repeat(reverse: true);
    _animation = Tween<double>(begin: 0.5, end: 1.5).animate(_controller);
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(title: Text("Explicit Animation")),
        body: Center(
          child: AnimatedBuilder(
            animation: _animation,
            builder: (context, child) {
              return Transform.scale(
                scale: _animation.value,
                child: child,
              );
            },
            child: Container(width: 100, height: 100, color: Colors.green),
          ),
        ),
      ),
    );
  }
}

8.2 Hero Animation

The Hero Animation allows smooth transitions between two pages when an element is shared across screens.


Example: Hero Animation

import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: FirstPage(),
    );
  }
}

class FirstPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text("Hero Animation")),
      body: Center(
        child: GestureDetector(
          onTap: () {
            Navigator.push(
              context,
              MaterialPageRoute(builder: (context) => SecondPage()),
            );
          },
          child: Hero(
            tag: 'hero-tag',
            child: Container(width: 100, height: 100, color: Colors.orange),
          ),
        ),
      ),
    );
  }
}

class SecondPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: Hero(
          tag: 'hero-tag',
          child: Container(width: 200, height: 200, color: Colors.orange),
        ),
      ),
    );
  }
}

8.3 Lottie Animations

Lottie is used to display JSON-based animations created with Adobe After Effects.


Steps to Implement Lottie

  1. Add lottie dependency in pubspec.yaml:
dependencies:
  lottie: ^2.6.0
  1. Use Lottie animation in Flutter:
import 'package:flutter/material.dart';
import 'package:lottie/lottie.dart';

class LottieAnimationExample extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: Lottie.asset('assets/animation.json'),
      ),
    );
  }
}

8.4 Custom Animations with AnimatedBuilder

AnimatedBuilder helps optimise animations by rebuilding only the necessary parts.


Example

AnimatedBuilder(
  animation: _controller,
  builder: (context, child) {
    return Transform.rotate(
      angle: _controller.value * 2 * 3.1415,
      child: child,
    );
  },
  child: Icon(Icons.refresh, size: 50),
)

8.5 Page Transitions

Flutter provides custom page transitions with PageRouteBuilder.


Example: Fade Transition

Navigator.push(
  context,
  PageRouteBuilder(
    pageBuilder: (context, animation, secondaryAnimation) => NextPage(),
    transitionsBuilder: (context, animation, secondaryAnimation, child) {
      return FadeTransition(opacity: animation, child: child);
    },
  ),
);

Conclusion

Mastering animations in Flutter enhances user experience significantly. By using implicit animations, explicit animations, Hero animations, Lottie animations, AnimatedBuilder, and custom page transitions, you can create stunning and interactive UI experiences.


Leave a Comment


Choose Colour