Fermer

octobre 14, 2019

Animation d'applications avec Flutter


À propos de l'auteur

Un développeur de logiciels à pile complète le jour et un développeur d'applications mobiles la nuit. Bien que je ne travaille pas, j'aime cuisiner et jouer à des jeux PC.
Plus d'informations sur
Shubham

Flutter fournit un excellent support d'animation pour les applications multiplates-formes. Cet article explore la nouvelle méthode non conventionnelle et un moyen plus simple d'ajouter des animations aux applications. En quoi consistent exactement ces nouveaux widgets «Animation et mouvement» et comment pouvons-nous les utiliser pour ajouter des animations simples et complexes?

Les applications de toutes les plateformes sont louées pour leur caractère intuitif, leur apparence agréable et le retour agréable des interactions de l'utilisateur. L’animation est l’un des moyens de le faire.

Flutter, un framework multiplate-forme, a mûri au cours des deux dernières années pour inclure l’assistance Web et de bureau. Il a acquis la réputation que les applications développées avec ce logiciel sont fluides et esthétiques. Avec son support d'animation riche, sa manière déclarative d'écrire son interface utilisateur, «Hot Reload» et d'autres fonctionnalités, il constitue désormais un cadre multi-plateformes complet.

Si vous débutez avec Flutter et souhaitez apprendre une méthode d'ajout non conventionnelle animation, alors vous êtes au bon endroit: nous allons explorer le domaine de l'animation et des widgets de mouvement, une manière implicite d'ajouter des animations.

Flutter est basé sur le concept de widgets. Chaque composant visuel d'une application est un widget. Imaginez-les comme des vues dans Android. Flutter prend en charge l'animation à l'aide d'une classe Animation, d'un objet «AnimationController» pour la gestion et «Tween» pour interpoler la plage de données. Ces trois composants fonctionnent ensemble pour fournir une animation fluide. Étant donné que cela nécessite la création manuelle et la gestion de l'animation, il s'agit d'une méthode explicite d'animation.

Permettez-moi maintenant de vous présenter les widgets d'animation et de mouvement. Flutter fournit de nombreux widgets qui prennent en charge l'animation de manière inhérente. Il n’est pas nécessaire de créer un objet d’animation ni un contrôleur, car toute l’animation est gérée par cette catégorie de widgets. Il suffit de choisir le widget approprié pour l’animation requise et de transmettre les valeurs de propriétés du widget à animer. Cette technique est une manière implicite d'animer.

Hiérarchie d'animation dans Flutter. ( Grand aperçu )

Le graphique ci-dessus présente la hiérarchie de l'animation dans Flutter, indiquant comment les animations explicites et implicites sont prises en charge.

Certains des widgets animés traités dans cet article sont: [19659012] AnimatedOpacity

  • AnimatedCrossFade
  • AnimatedAlign
  • AnimatedPadding
  • AnimatedSize
  • AnimatedPositioned .
  • Flutter fournit non seulement des widgets animés prédéfinis, mais également un widget générique appelé Animated qui peut être utilisé pour créer des widgets personnalisés implicitement animés. Comme leur nom l'indique, ces widgets appartiennent à la catégorie des widgets animés et de mouvement et possèdent donc certaines propriétés communes qui nous permettent de rendre les animations plus lisses et plus esthétiques.

    Permettez-moi d'expliquer ces propriétés communes maintenant, car elles vont être utilisé plus tard dans tous les exemples.

    • duration
      La durée sur laquelle animer les paramètres.
    • reverseDuration
      La durée de l'animation inversée.
    • Curve
      La courbe à appliquer lors de l'animation. Les paramètres. Les valeurs interpolées peuvent être extraites d’une distribution linéaire ou, le cas échéant, d’une courbe.

    Commençons par créer une application simple que nous appellerons «Citée». Il affichera une citation aléatoire à chaque démarrage de l'application. Deux choses à noter: premièrement, toutes ces citations seront codées en dur dans l’application; et en second lieu, aucune donnée d'utilisateur ne sera sauvegardée.

    Remarque : Les fichiers de ces exemples sont tous accessibles sur GitHub

    Getting Started

    ] Flutter doit être installé et vous devrez vous familiariser avec le flux de base avant de poursuivre. " Utiliser le flottement de Google pour un développement réellement multiplate-forme mobile ".

    Créer un nouveau projet Flutter dans Android Studio.

    Nouveau menu Projet flottant dans Android Studio. ( Grand aperçu )

    Ceci ouvrira un nouvel assistant de projet dans lequel vous pourrez configurer les bases du projet.

    Écran de sélection du type de projet Flutter. ( Grand aperçu )

    Dans l'écran de sélection du type de projet, il existe différents types de projets Flutter, chacun correspondant à un scénario spécifique. Pour ce tutoriel, choisissez Application Flutter . appuyez sur Suivant .

    Vous devez maintenant entrer des informations spécifiques au projet: nom et chemin du projet, domaine de l'entreprise, etc. Regardez l'image ci-dessous.

    Écran de configuration de l'application Flutter. ( Grand aperçu )

    Ajoutez le nom du projet, le chemin d'accès du SDK Flutter, son emplacement et une description facultative du projet. Appuyez sur Suivant .

    Écran Nom du package d’application Flutter. ( Grand aperçu )

    Chaque application (que ce soit Android ou iOS) nécessite un nom de package unique. En règle générale, vous utilisez l'inverse du domaine de votre site Web; par exemple, com.google ou com.yahoo. Appuyez sur Terminer pour générer une application Flutter fonctionnelle.

    Le projet exemple généré. ( Grand aperçu )

    Une fois le projet généré, vous devriez voir l'écran ci-dessus. Ouvrez le fichier main.dart (mis en évidence dans la capture d'écran). Ceci est le fichier principal de l'application. L'exemple de projet est complet en soi et peut être exécuté directement sur un émulateur ou un périphérique physique sans aucune modification.

    Remplacez le contenu du fichier main.dart par le fragment de code suivant: [19659043] import 'package: animated_widgets / FirstPage.dart';
    importer 'package: flutter / material.dart';

    void main () => runApp (MyApp ());
    La classe MyApp étend StatelessWidget {
     @passer outre
     Construction du widget (contexte BuildContext) {
       retourner MaterialApp (
         titre: 'Widgets animés',
         debugShowCheckedModeBanner: false,
         thème: ThemeData (
           primarySwatch: Colors.blue,
           accentColor: Colors.redAccent,
         ),
         home: FirstPage (),
       )
     }
    }

    Ce code nettoie le fichier main.dart en ajoutant simplement des informations simples relatives à la création d'une nouvelle application. La classe MyApp renvoie un objet: un widget MaterialApp qui fournit la structure de base pour la création d'applications conformes à Material Design . Pour rendre le code plus structuré, créez deux nouveaux fichiers de fléchettes dans le dossier lib : FirstPage.dart et Quotes.dart .

    The FirstPage.dart fichier. ( Grand aperçu )

    FirstPage.dart contiendra tout le code responsable de tous les éléments visuels (widgets) requis pour notre application citée. Toute l'animation est gérée dans ce fichier.

    Note : Plus tard dans l'article, tous les extraits de code pour chaque widget animé sont ajoutés à ce fichier en tant qu'enfants du widget Scaffold. Pour plus d'informations, Cet exemple sur GitHub pourrait être utile.

    Commencez par ajouter le code suivant à FirstPage.dart . C'est le code partiel auquel d'autres éléments seront ajoutés plus tard.

     import 'dart: math';
    
    importer 'package: animated_widgets / Quotes.dart';
    importer 'package: flutter / material.dart';
    
    
    La classe FirstPage étend StatefulWidget {
     @passer outre
     Etat  createState () {
       retourne FirstPageState ();
     }
    }
    
    La classe FirstPageState étend l'État  avec TickerProviderStateMixin {
    
     bool showNextButton = false;
     bool showNameLabel = false;
     bool alignTop = false;
     bool augmentationLeftPadding = false;
     bool showGreetings = false;
     bool showQuoteCard = false;
     Nom de la chaîne = '';
    
    
     double screenWidth;
     double screenHeight;
     Citation de chaîne;
    
    
     @passer outre
     void initState () {
       super.initState ();
       Aléatoire Aléatoire = Nouveau Aléatoire ();
       int quoteIndex = random.nextInt (Quotes.quotesArray.length);
       quote = Quotes.quotesArray [quoteIndex];
     }
    
     @passer outre
     Construction du widget (contexte BuildContext) {
    
       screenWidth = MediaQuery.of (context) .size.width;
       screenHeight = MediaQuery.of (context) .size.height;
    
       retour échafaudage (
         appBar: _getAppBar (),
         corps: pile (
           enfants: [
             // All other children will be added here.
          // In this article, all the children widgets are contained
          // in their own separate methods.
          // Just method calls should be added here for the respective child.
           ],
         ),
       )
     }
    } 
    Le fichier Quotes.dart. ( Grand aperçu )

    Le fichier Quotes.dart contient une liste de toutes les citations codées en dur. Un point à noter ici est que la liste est un objet statique. Cela signifie qu'il peut être utilisé à d'autres endroits sans créer un nouvel objet de la classe Quotes. Ceci est choisi par conception, car la liste ci-dessus est simplement un utilitaire.

    Ajoutez le code suivant à ce fichier:

     class Quotes {
     statique fixe quotesArray = [
       "Good, better, best. Never let it rest. 'Til your good is better and your better is best",
       "It does not matter how slowly you go as long as you do not stop.",
       "Only I can change my life. No one can do it for me."
     ];
    } 

    Le squelette du projet est prêt, expliquez-le un peu plus en détail.

    AnimatedOpacity

    Pour ajouter une touche personnelle à l'application, il serait bon de connaître le nom de l'utilisateur, demandons-le et montrons un bouton suivant. Tant que l'utilisateur n'a pas saisi son nom, ce bouton est masqué et il s'affiche gracieusement lorsqu'un nom est donné. Nous avons besoin d'une sorte d'animation de visibilité pour le bouton, mais existe-t-il un widget pour cela? Oui, il y en a.

    Entrez AnimatedOpacity . Ce widget s'appuie sur le widget Opacity en ajoutant un support implicite d'animation. Comment l'utilisons-nous? Rappelez-vous notre scénario: nous devons afficher un bouton suivant avec une visibilité animée. Nous intégrons le widget Button dans le widget AnimatedOpacity introduisons des valeurs appropriées et ajoutons une condition pour déclencher l'animation – et Flutter peut gérer le reste.

     _getAnimatedOpacityButton () {
      retourne AnimatedOpacity (
        duration: Duration (seconds: 1),
        reverseDuration: Durée (secondes: 1),
        courbe: Curves.easeInOut,
        opacité: showNextButton? dix,
        enfant: _getButton (),
      )
    } 
    Animation d'opacité du bouton suivant. ( Grand aperçu )

    Le widget AnimatedOpacity a deux propriétés obligatoires:

    • opacity
      Une valeur de 1 signifie complètement visible; 0 (zéro) signifie caché. Pendant l'animation, Flutter interpole les valeurs entre ces deux extrêmes. Vous pouvez voir comment une condition est placée pour modifier la visibilité, déclenchant ainsi une animation.
    • child
      Le widget enfant qui aura sa visibilité animée.

    Vous devez maintenant comprendre à quel point il est simple d'ajouter une animation de visibilité. avec le widget implicite. Et tous ces widgets suivent les mêmes directives et sont faciles à utiliser. Passons au suivant.

    AnimatedCrossFade

    Nous avons le nom de l’utilisateur, mais le widget attend toujours l’entrée. Dans l'étape précédente, lorsque l'utilisateur entre son nom, nous affichons le bouton suivant. Maintenant, lorsque l'utilisateur appuie sur le bouton, je souhaite arrêter d'accepter les entrées et afficher le nom saisi. Bien sûr, il existe de nombreuses façons de le faire, mais nous pouvons peut-être cacher le widget de saisie et afficher un widget de texte non modifiable. Essayons-le à l'aide du widget AnimatedCrossFade .

    Ce widget nécessite deux enfants, car le widget effectue un fondu enchaîné entre eux en fonction de certaines conditions. Une chose importante à garder à l'esprit lors de l'utilisation de ce widget est que les deux enfants doivent avoir la même largeur. Si la hauteur est différente, le widget le plus grand est coupé du bas. Dans ce scénario, deux widgets seront utilisés comme enfants: entrée et libellé.

     _getAnimatedCrossfade () {) {
    
      retourne AnimatedCrossFade (
    
        duration: Duration (seconds: 1),
    
        alignement: Alignment.center,
    
        reverseDuration: Durée (secondes: 1),
    
        firstChild: _getNameInputWidget (),
    
        firstCurve: Curves.easeInOut,
    
        secondChild: _getNameLabelWidget (),
    
        secondCurve: Curves.easeInOut,
    
        crossFadeState: showNameLabel? CrossFadeState.showSecond: CrossFadeState.showFirst,
    
      )
    
    } 
    Fondu enchaîné entre le widget de saisie et le widget de nom. ( Grand aperçu )

    Ce widget nécessite un jeu de paramètres obligatoires différent:

    • crossFadeState
      Cet état détermine quel enfant afficher.
    • firstChild
      Spécifie le premier enfant. pour ce widget
    • secondChild
      Spécifie le deuxième enfant

    AnimatedAlign

    À ce stade, l'étiquette de nom est positionnée au centre de l'écran. Cela aura l'air beaucoup mieux en haut, car nous avons besoin du centre de l'écran pour afficher les citations. En termes simples, l'alignement du widget de libellé doit être modifié du centre vers le haut. Et ne serait-il pas agréable d’animer ce changement d’alignement avec la précédente animation de fondu enchaîné? Faisons-le.

    Comme toujours, plusieurs techniques peuvent être utilisées pour y parvenir. Étant donné que le widget étiquette de nom est déjà centré, l'animation de son alignement serait beaucoup plus simple que de manipuler les valeurs supérieure et gauche du widget. Le widget AnimatedAlign est idéal pour ce travail.

    Pour lancer cette animation, un déclencheur est requis. Le seul but de ce widget est d’animer le changement d’alignement, de sorte qu’il n’a que quelques propriétés: ajouter un enfant, définir son alignement, déclencher le changement d’alignement, et c’est ça.

     _getAnimatedAlignWidget () {
    
      return AnimatedAlign (
    
    duration: Duration (seconds: 1),
    
    courbe: Curves.easeInOut,
    
    alignement: alignTop? Alignment.topLeft: Alignment.center,
    
    enfant: _getAnimatedCrossfade (),
    
      )
    
    } 
    Animation d'alignement du widget de nom. ( Grand aperçu )

    Il n'a que deux propriétés obligatoires:

    • enfant:
      L'enfant dont l'alignement sera modifié.
    • alignement:
      Valeur d'alignement requise.

    ] Ce widget est très simple mais les résultats sont élégants. De plus, nous avons vu avec quelle facilité nous pouvions utiliser deux widgets animés différents pour créer une animation plus complexe. C’est la beauté des widgets animés.

    AnimatedPadding

    Nous avons maintenant le nom de l’utilisateur au sommet, animé en douceur et sans effort, avec différents types de widgets animés. Ajoutons une salutation «Bonjour» avant le nom. L'ajout d'un widget de texte avec la valeur «Hi» en haut le recouvrira, ce qui ressemblera à l'image ci-dessous.

    Les widgets de bienvenue et de nom se chevauchent. ( Grand aperçu )

    Que se passe-t-il si le widget nom du texte avait un rembourrage à gauche? Augmenter le remplissage gauche fonctionnera certainement, mais attendez: pouvons-nous augmenter le remplissage avec une animation? Oui, et c'est ce que AnimatedPadding fait. Pour que tout cela soit plus beau, faisons fondre le widget de texte d'accueil et augmentez simultanément le remplissage de celui-ci.

     _getAnimatedPaddingWidget () {
    
      retourne AnimatedPadding (
    
        duration: Duration (seconds: 1),
    
        courbe: Curves.fastOutSlowIn,
    
        padding: augmentationLeftPadding? EdgeInsets.only (gauche: 28.0): EdgeInsets.only (gauche: 0),
    
        enfant: _getAnimatedCrossfade (),
    
      )
    
    } 

    Étant donné que l'animation ci-dessus ne devrait avoir lieu qu'une fois l'alignement animé précédent terminé, nous devons différer le déclenchement de cette animation. En résumant brièvement le sujet, c’est un bon moment pour parler d’un mécanisme populaire permettant d’attendre le retard. Flutter fournit plusieurs de ces techniques, mais le constructeur Future.delayed est l’une des approches les plus simples, les plus propres et les plus lisibles. Par exemple, pour exécuter un morceau de code après 1 seconde:

     Future.delayed (Durée (secondes: 1), () {
        somme = a + b; // Cette somme sera calculée après 1 seconde.
        imprimer (somme);
    }); 

    La durée du retard étant déjà connue (calculée à partir des durées de l'animation précédente), l'animation peut être déclenchée après cet intervalle.

     // Affichage de “Hi” après 1 seconde - déclencheur de visibilité des messages d'accueil.
    _showGreetings () {
      Future.delayed (Durée (secondes: 1), () {
        setState (() {
            showGreetings = true;
        });
      });
    }
    
    // Augmentation du padding pour le widget d'étiquette de nom après 1 seconde - augmentation du déclencheur de padding.
    _increaseLeftPadding () {
      Future.delayed (Durée (secondes: 1), () {
        setState (() {
        augmentationLeftPadding = true;
        });
      });
    } 
    Animation de remplissage du widget de nom. ( Grand aperçu )

    Ce widget n'a que deux propriétés obligatoires:

    • child
      L'enfant à l'intérieur de ce widget, auquel le remplissage sera appliqué.
    • padding
      Le montant

    AnimatedSize

    De nos jours, toute application ayant une sorte d'animation inclut un zoom avant ou arrière sur des composants visuels pour attirer l'attention des utilisateurs (communément appelée animation de redimensionnement). Pourquoi ne pas utiliser la même technique ici? Nous pouvons montrer à l'utilisateur une citation de motivation qui effectue un zoom avant du centre de l'écran. Permettez-moi de vous présenter le widget AnimatedSize qui active les effets de zoom avant et arrière, contrôlés en modifiant la taille de son enfant.

    Ce widget est un peu différent des autres lorsqu'il vient aux paramètres requis. Nous avons besoin de ce que Flutter appelle un «ticker». Flutter dispose d'une méthode permettant aux objets de savoir quand un nouvel événement frame est déclenché. Cela peut être considéré comme quelque chose qui envoie un signal disant: «Faites-le maintenant! … Fais le maintenant! … Fais le maintenant! … ”

    Le widget AnimatedSize nécessite une propriété – vsync – qui accepte un fournisseur de tickers. Le moyen le plus simple d'obtenir un fournisseur de tickers est d'ajouter un Mixin à la classe. Il existe deux implémentations de base du fournisseur de tickers: SingleTickerProviderStateMixin qui fournit un seul ticker; et TickerProviderStateMixin qui en fournit plusieurs.

    L'implémentation par défaut d'un ticker est utilisée pour marquer les images d'une animation. Dans ce cas, ce dernier est utilisé. En savoir plus sur mixins .

     // Méthode d'assistance pour créer le widget Carte de citations.
    _getQuoteCardWidget () {
      carte de retour (
        couleur: Colors.green,
        élévation: 8.0,
        child: _getAnimatedSizeWidget (),
      )
    }
    // Méthode d'assistance pour créer un widget de taille animée et définir ses propriétés.
    _getAnimatedSizeWidget () {
      retourne AnimatedSize (
        duration: Duration (seconds: 1),
        courbe: Curves.easeInOut,
        vsync: ceci,
        enfant: _getQuoteContainer (),
      )
    }
    // Méthode d'assistance pour créer le widget de conteneur de citations avec des tailles différentes.
    _getQuoteContainer () {
      conteneur de retour (
        hauteur: showQuoteCard? 100: 0,
        largeur: showQuoteCard? largeur d'écran - 32: 0,
        enfant: Centre (
        enfant: Rembourrage (
            padding: EdgeInsets.symmetric (horizontal: 16),
            child: Texte (citation, style: TextStyle (color: Colors.white, fontWeight: FontWeight.w400, fontSize: 14),),
        ),
        ),
      )
    }
    // Déclencheur utilisé pour afficher le widget de carte de citation.
    _showQuote () {
      Future.delayed (Durée (secondes: 2), () {
        setState (() {
            showQuoteCard = true;
        });
      });
    } 
    Animation de redimensionnement du widget Citations. ( Grand aperçu )

    Propriétés obligatoires pour ce widget:

    • vsync
      Le fournisseur de ticker requis pour coordonner les modifications d'animation et de cadre. <
    • child
      L'enfant dont la taille change sera animé.

    L’animation de zoom avant et arrière est désormais facile à apprivoiser.

    AnimatedPositioned

    Super! Les guillemets permettent d’agrandir le centre pour attirer l’attention de l’utilisateur. Et si il glissait depuis le bas en zoomant? Essayons. Ce mouvement implique de jouer avec la position du widget de devis et d'animer les modifications des propriétés de position. AnimatedPositioned est le candidat idéal.

    Ce widget transforme automatiquement la position de l’enfant sur une durée donnée chaque fois que la position spécifiée change. Un point à noter: il ne fonctionne que si son widget parent est une «pile». Ce widget est assez simple et facile à utiliser. Voyons voir.

     // Méthode auxiliaire pour créer le widget animé positionné.
    // Avec les changements de position basés sur l'indicateur “showQuoteCard”.
    _getAnimatedPositionWidget () {
      return AnimatedPositioned (
        duration: Duration (seconds: 1),
        courbe: Curves.easeInOut,
        enfant: _getQuoteCardWidget (),
        en haut: showQuoteCard? screenHeight / 2 - 100: screenHeight,
        à gauche:! showQuoteCard? largeur d'écran / 2: 12,
      )
    } 
    Position avec l'animation de redimensionnement des citations. ( Grand aperçu )

    Ce widget n'a qu'une propriété obligatoire:

    • child
      Le widget dont la position sera modifiée.

    Si la taille de l'enfant ne devrait pas changer En plus de sa position, une alternative plus performante à ce widget serait SlideTransition .

    Voici notre animation complète:

    Tous les widgets animés réunis. ( Grand aperçu )

    Conclusion

    Les animations font partie intégrante de l'expérience utilisateur. Les applications statiques ou les applications avec animation janky non seulement réduisent la rétention des utilisateurs, mais également la réputation du développeur de fournir des résultats.

    Aujourd'hui, les applications les plus populaires proposent une sorte d'animation subtile qui ravira les utilisateurs. Les réactions animées aux demandes des utilisateurs peuvent également les amener à explorer davantage. Flutter offre de nombreuses fonctionnalités pour le développement multiplate-forme, y compris un support riche pour des animations fluides et réactives.

    Flutter offre une excellente prise en charge des plug-ins, ce qui nous permet d'utiliser les animations d'autres développeurs. Maintenant que la version 1.9 est arrivée à maturité, avec autant d’amour de la part de la communauté, Flutter va sûrement s’améliorer à l’avenir. J’aimerais dire que c’est le moment idéal pour apprendre le flutter!

    Ressources supplémentaires

     La rédaction de Smashing (dm, og, yk, il)




    Source link