Avez-vous une question? (216) 97 656 803 hajjriadh@gmail.com
Flutter

Créer des animations dans Flutter

Un cours complet pour maîtriser Créer des animations dans Flutter.

0 chapitres 0 QCM Accès gratuit
  1. Objectif du Tutoriel

  2. Introduction aux animations dans Flutter

    • Flutter propose plusieurs types d'animations, notamment :
      • Animations implicites : Faciles à utiliser, elles permettent de modifier les propriétés des widgets avec des transitions douces.
      • Animations explicites: Donnent plus de contrôle pour des animations complexes grâce à des objets comme AnimationController.
  3. Préparation de l’environnement

    • Assurez-vous que votre environnement Flutter est configuré correctement. Créez un nouveau projet en exécutant la commande suivante dans votre terminal :flutter create animation_demo
    • Accédez au dossier :cd animation_demo
    • Ouvrez le projet dans votre éditeur préféré, comme VS Code ou Android Studio.
  4. Création d’animations implicites

    • Les animations implicites sont créées grâce à des widgets qui gèrent déjà certaines animations pour vous, car ils implémentent la classe ImplicitlyAnimatedWidget. Il s'agit d'une classe qui anime les changements de propriétés. Par exemple, si un AnimatedContainer voit sa propriété largeur changer, la reconstruction ne se fera pas en un coup comme habituellement, mais en plusieurs fois afin de créer une animation qui se charge de la transition entre l'état initial et le nouvel état.
    • Flutter possède une série de widgets, qui sont simplement des versions animées de widgets déjà existants. Ces widgets créent une animation à chaque fois qu'une des propriétés du widget change et se nomment (entre autres) les AnimatedFoo.
    • Liste des AnimatedFoo :
      • AnimatedContainer
      • AnimatedAlign
      • AnimatedDefaultTextStyle
      • AnimatedOpacity
      • AnimatedPadding
      • AnimatedPhysicalModel
      • AnimatedPositioned
      • AnimatedPositionedDirectional
      Exemple 1 : Changement de couleur avec AnimatedContainer
        import 'package:flutter/material.dart';
        
        void main() => runApp(MyApp());
        
        class MyApp extends StatelessWidget {
          @override
          Widget build(BuildContext context) {
            return MaterialApp(
              home: AnimationDemo(),
            );
          }
        }
        
        class AnimationDemo extends StatefulWidget {
          @override
          _AnimationDemoState createState() => _AnimationDemoState();
        }
        
        class _AnimationDemoState extends State {
          bool isSelected = false;
        
          @override
          Widget build(BuildContext context) {
            return Scaffold(
              appBar: AppBar(title: Text('Animation Implicite')),
              body: Center(
                child: GestureDetector(
                  onTap: () {
                    setState(() {
                      isSelected = !isSelected;
                    });
                  },
                  child: AnimatedContainer(
                    duration: Duration(seconds: 1),
                    width: isSelected ? 200.0 : 100.0,
                    height: isSelected ? 100.0 : 200.0,
                    color: isSelected ? Colors.blue : Colors.red,
                    curve: Curves.easeInOut,
                  ),
                ),
              ),
            );
          }
        }
    • Explication :
      • AnimatedContainer: Gère automatiquement la transition de ses propriétés comme la taille, la couleur, etc.
      • Duration: Définit la durée de l’animation.
      • Curve: Ajoute une courbe pour personnaliser le comportement de l’animation.
    • Exemple 2 : Animation d'un Container avec AnimatedContainer dans Flutter
        import 'package:flutter/material.dart';
        
        void main() => runApp(MyApp());
        
        class MyApp extends StatelessWidget {
          @override
          Widget build(BuildContext context) {
            return MaterialApp(
              home: MyHomePage(),
            );
          }
        }
        
        class MyHomePage extends StatefulWidget {
          @override
          _MyHomePageState createState() => _MyHomePageState();
        }
        
        class _MyHomePageState extends State {
          // Define some variables to control the animation.
          bool _isContainerExpanded = false;
          Color _containerColor = Colors.blue;
          double _containerHeight = 100.0;
          double _containerWidth = 100.0;
        
          // Function to toggle the animation.
          void _toggleAnimation() {
            setState(() {
              _isContainerExpanded = !_isContainerExpanded;
              // Update color, height, and width based on the animation state.
              _containerColor = _isContainerExpanded ? Colors.green : Colors.blue;
              _containerHeight = _isContainerExpanded ? 200.0 : 100.0;
              _containerWidth = _isContainerExpanded ? 200.0 : 100.0;
            });
          }
        
          @override
          Widget build(BuildContext context) {
            return Scaffold(
              appBar: AppBar(
                title: Text('AnimatedContainer Example'),
              ),
              body: Center(
                child: Column(
                  mainAxisAlignment: MainAxisAlignment.center,
                  children: [
                    // AnimatedContainer with changing color, height, and width.
                    AnimatedContainer(
                      duration: Duration(seconds: 1), // Animation duration.
                      curve: Curves.easeInOut, // Animation curve.
                      color: _containerColor, // Color that changes.
                      height: _containerHeight, // Height that changes.
                      width: _containerWidth, // Width that changes.
                      child: Center(
                        child: Text(
                          'Tap me!',
                          style: TextStyle(color: Colors.white),
                        ),
                      ),
                    ),
                    SizedBox(height: 20.0),
                    // Button to trigger the animation.
                    ElevatedButton(
                      onPressed: _toggleAnimation,
                      child: Text('Toggle Animation'),
                    ),
                  ],
                ),
              ),
            );
          }
        }
        
    • Explication :
      • Cet exemple illustre comment utiliser un widget AnimatedContainer pour animer plusieurs propriétés d'un conteneur telles que la couleur, la hauteur et la largeur. L'animation est déclenchée par un bouton qui modifie l'état du conteneur.
      • Déclaration des variables d'état:
        • _isContainerExpanded: Contrôle si le conteneur est agrandi ou non.
        • _containerColor, _containerHeight, _containerWidth: Ces variables définissent les propriétés du conteneur et changent en fonction de l'état.
      • Animation avec AnimatedContainer :
        • Le widget AnimatedContainer permet de changer ses propriétés avec une transition animée.
        • Les propriétés modifiées sont :
        • Couleur (color) : Change entre Colors.blue et Colors.green.
        • Hauteur (height) et Largeur (width): Augmentent ou diminuent.
      • Bouton d'interaction :
      • Le bouton ElevatedButton déclenche la méthode _toggleAnimation, qui met à jour les propriétés du conteneur via setState().
      • Cela entraîne un redessin du widget avec des transitions douces définies par AnimatedContainer.
      • Personnalisation de l'animation :
        • Duration : Définit la durée de l'animation (1 seconde ici).
        • Curve: Ajoute une courbe d’animation (Curves.easeInOut), rendant la transition plus fluide.
  5. Création d’animations explicites

      Exemple 2 : Animation avec AnimationController et Tween
        import 'package:flutter/material.dart';
        
        void main() => runApp(MyApp());
        
        class MyApp extends StatelessWidget {
          @override
          Widget build(BuildContext context) {
            return MaterialApp(
              home: AnimationControllerDemo(),
            );
          }
        }
        
        class AnimationControllerDemo extends StatefulWidget {
          @override
          _AnimationControllerDemoState createState() =>
              _AnimationControllerDemoState();
        }
        
        class _AnimationControllerDemoState extends State
            with SingleTickerProviderStateMixin {
          late AnimationController _controller;
          late Animation _animation;
        
          @override
          void initState() {
            super.initState();
            _controller = AnimationController(
              duration: const Duration(seconds: 2),
              vsync: this,
            );
        
            _animation = Tween(begin: 50.0, end: 200.0).animate(
              CurvedAnimation(parent: _controller, curve: Curves.bounceIn),
            );
        
            _controller.repeat(reverse: true);
          }
        
          @override
          void dispose() {
            _controller.dispose();
            super.dispose();
          }
        
          @override
          Widget build(BuildContext context) {
            return Scaffold(
              appBar: AppBar(title: Text('Animation Explicite')),
              body: Center(
                child: AnimatedBuilder(
                  animation: _animation,
                  builder: (context, child) {
                    return Container(
                      width: _animation.value,
                      height: _animation.value,
                      color: Colors.green,
                    );
                  },
                ),
              ),
            );
          }
        }
    • Explication :
      • AnimationController: Contrôle l’animation, comme sa durée et son état.
      • Tween: Définit la plage de valeurs entre le début et la fin.
      • CurvedAnimation: Ajoute une courbe à l’animation.
      • AnimatedBuilder: Optimise le rendu en reconstruisant uniquement la partie animée.
  6. Animation combinée

      Exemple 3 : Rotation et Opacité
        import 'package:flutter/material.dart';
        
        void main() => runApp(MyApp());
        
        class MyApp extends StatelessWidget {
          @override
          Widget build(BuildContext context) {
            return MaterialApp(
              home: CombinedAnimationDemo(),
            );
          }
        }
        
        class CombinedAnimationDemo extends StatefulWidget {
          @override
          _CombinedAnimationDemoState createState() => _CombinedAnimationDemoState();
        }
        
        class _CombinedAnimationDemoState extends State
            with SingleTickerProviderStateMixin {
          late AnimationController _controller;
        
          @override
          void initState() {
            super.initState();
            _controller = AnimationController(
              duration: const Duration(seconds: 2),
              vsync: this,
            )..repeat();
          }
        
          @override
          void dispose() {
            _controller.dispose();
            super.dispose();
          }
        
          @override
          Widget build(BuildContext context) {
            return Scaffold(
              appBar: AppBar(title: Text('Animation Combinée')),
              body: Center(
                child: AnimatedBuilder(
                  animation: _controller,
                  child: Container(
                    width: 100.0,
                    height: 100.0,
                    color: Colors.purple,
                  ),
                  builder: (context, child) {
                    return Transform.rotate(
                      angle: _controller.value * 2.0 * 3.14,
                      child: Opacity(
                        opacity: _controller.value,
                        child: child,
                      ),
                    );
                  },
                ),
              ),
            );
          }
        }
    • Explication :
      • Transform.rotate : Applique une rotation.
      • Opacity: Modifie la transparence.
      • Les deux sont combinés pour un effet fluide.
  7. Animation avancée avec des packages

    • Flutter propose des bibliothèques pour simplifier les animations complexes :
    • flutter_animate: Simple et puissant pour les animations.
    • rive: Pour des animations vectorielles interactives.
    • lottie : Pour lire des animations JSON créées avec After Effects.
    • Ajoutez un package dans pubspec.yaml
    • dependencies:
        flutter_animate: ^4.0.0
      Exemple avec flutter_animate
        import 'package:flutter/material.dart';
        import 'package:flutter_animate/flutter_animate.dart';
        
        void main() => runApp(MyApp());
        
        class MyApp extends StatelessWidget {
          @override
          Widget build(BuildContext context) {
            return MaterialApp(
              home: Scaffold(
                appBar: AppBar(title: Text('Animation avec Flutter Animate')),
                body: Center(
                  child: Text('Bonjour Flutter!')
                      .animate()
                      .fadeIn(duration: 1000.ms)
                      .scale(),
                ),
              ),
            );
          }
        }
    • Bonnes pratiques

      • Utilisez les animations uniquement lorsque cela améliore l’expérience utilisateur.
      • Testez les performances, surtout sur des appareils bas de gamme.
      • Préférez les animations implicites pour les besoins simples.