À propos de Flutter, en bref: les bases

À propos de Flutter, en bref: les bases


Après le rapport de Yura Luchaninov , j'ai décidé d'essayer Flutter par moi-même. Pour étirer le cerveau, et donc il y avait de quoi se détendre avec les hommes dans la cuisine. Les choses ont disparu. J'ai commencé à regarder, puis à lire, puis à écrire. Et tout semble fonctionner, les applications sont lancées, et ce qu'elles expliquent est compréhensible, tout est simple. Mais pas sans «mais» - tout le monde n'explique pas. Et puisque la plate-forme, le PJ, les approches et même le sujet sont nouveaux pour moi, ce genre de contrariété, parce que vous "ne commencez pas", et vous ne savez même pas quoi google: Dart / Flutter / Window / Screen / Route / Widget?


Bien sûr, je ne voulais pas relire toute la documentation de Dart, Flutter et ses widgets, car je n'avais pas beaucoup de temps, et je voulais juste regarder de plus près Flutter. Ce serait génial s'il y avait un petit guide qui décrit tout ce dont vous avez besoin, mais pas plus, pour comprendre et écrire des applications pas trop compliquées sur Flutter!


À propos du guide


La plupart des articles sur ce sujet sont bien écrits et pas compliqués. Le problème est que la plupart d'entre eux nécessitent des connaissances qui sont considérées comme des fondamentaux, qui, cependant, ne sont pas mentionnés dans d'autres articles décrivant les bases. Dans cette série d'articles, je veux rectifier cette situation. Commençons à zéro et, sans laisser aucune de ces réponses sans attention, nous lancerons une ou plusieurs applications. Au cours de ce processus, nous apprendrons à utiliser tous les composants principaux , à créer une interface unique , à travailler avec des modules natifs et, bien sûr, à assembler votre application pour les deux plates-formes .


J'écrirai du point de vue d'un développeur web. La plupart d'entre vous connaissent probablement la pile Web, et l'analogie avec la plate-forme familière est meilleure que l'analogie avec la construction de maisons ou autre chose, Animal, Dog, Foo, Bar ...


Je vais essayer de résumer brièvement pour ne pas tarder. Et pour les plus curieux, je laisserai des liens utiles sur les sujets abordés.


À propos de la plateforme


Flutter est une plateforme jeune mais très prometteuse qui a déjà attiré l'attention des grandes entreprises qui ont lancé leurs applications . Cette plateforme est intéressante pour sa simplicité comparable au développement d'applications web, et la rapidité de travail à égalité avec les applications natives. Des performances d'application et une vitesse de développement élevées sont obtenues grâce à plusieurs techniques:


  • Contrairement à de nombreuses plates-formes mobiles bien connues d'aujourd'hui, Flutter n'utilise JavaScript sous aucune forme. En tant que langage de programmation pour Flutter, ils ont choisi Dart, qui est compilé en code binaire, atteignant ainsi la vitesse des opérations comparable à Objective-C, Swift, Java ou Kotlin.
  • Flutter n'utilise pas de composants natifs , encore une fois, sous quelque forme que ce soit, vous n'avez donc pas besoin d'écrire de couches pour communiquer avec eux. Au lieu de cela, comme les moteurs de jeu (et vous savez que les jeux ont une interface utilisateur très dynamique), il dessine lui-même toute l'interface. Boutons, texte, éléments multimédias, arrière-plan - tout cela est dessiné à l'intérieur du moteur graphique dans Flutter lui-même. Après ce qui précède, il convient de noter que l'application «Hello World» sur Flutter prend très peu de place: iOS ≈ 2,5 Mo et Android ≈ 4 Mo.
  • Flutter utilise une approche déclarative inspirée du framework web ReactJS basé sur des widgets (dans le monde du web appelés composants) pour construire l'interface utilisateur. Pour une augmentation encore plus grande de la vitesse de l'interface, les widgets sont redessinés selon les besoins - uniquement lorsque quelque chose a changé en eux (tout comme Virtual DOM le fait dans le monde du web front-end).
  • En plus de cela, le framework a un Hot-Reload intégré , si familier au Web, et qui n'était toujours pas disponible sur les plateformes natives.

Sur les avantages pratiques de ces facteurs, je recommande fortement de lire l' article du développeur Android qui a réécrit son application de Java vers Dart et a partagé ses impressions. Ici, je viens de retirer le nombre de fichiers / lignes de code qu'il a nommés avant (écrit en Java) - 179/12176, et après (réécrit en Dart) - 31/1735. Dans la documentation, vous trouverez une description détaillée des caractéristiques techniques de la plateforme . Et voici un autre lien, si vous êtes intéressé à voir d'autres exemples d'applications fonctionnelles .


À propos de Dart


Dart est un langage de programmation dans lequel nous devons écrire des applications pour Flutter. C'est très simple, et si vous avez de l'expérience avec Java ou JavaScript, vous l'apprendrez rapidement.


J'ai essayé d'écrire un article sur Dart, essayant de décrire uniquement le minimum nécessaire pour apprendre Flutter. Mais il y a tellement de nuances dans cette langue que, malgré plusieurs tentatives pour écrire un tel article, je ne pouvais toujours pas le rendre assez complet et en même temps court. En revanche, les auteurs de A Tour of the Dart Language ont fait un excellent travail.


À propos de la formation


Ce sujet, comme Dart, est très bien décrit dans le guide officiel. Je ne pouvais que le copier ici, mais je ne le ferai pas.


Sans rien attendre, nous allons sur la page du guide d'installation , sélectionnons la plateforme et suivons les étapes pour installer la plateforme sur notre système. Dans notre éditeur, nous connecterons des plugins. Dans le même guide, il y a une instruction pour configurer VS Code et IntelliJ . Il existe également des plugins pour Dart et Flutter pour votre éditeur (vous devez généralement en installer deux). Nous lançons l'application et vérifions ses performances .


Astuce pour les utilisateurs OSX. Je suis désolé pour l'espace occupé par les cadres peints du téléphone dans l'émulateur iOS, alors je les ai éteints et je suis passé à l'iPhone 8 (ce n'est pas si «long»):


  • Hardware → Device → iOS # → iPhone 8
  • Window → Show Device Bezels

Vous pouvez vivre sans boutons, car il existe des raccourcis clavier: Shift + Cmd + H - c'est la maison, Cmd + Right - et c'est pour retourner le téléphone, le reste peut être trouvé dans le menu Hardware . Mais je vous conseille d'activer le clavier à l'écran, car il est important de comprendre s'il est possible de travailler avec l'application lorsque la moitié de l'écran est régulièrement bloquée par le clavier: Cmd + K (fonctionne lorsque l'accent est mis sur un champ de saisie).


iPhone 8 et iPhone X avec cadres
iPhone 8 et iPhone X avec cadres


iPhone 8 et iPhone X sans bordure
iPhone 8 et iPhone X sans bordure


À propos de la structure


Nous allons aller dans le dossier avec l'application générée et voir ce que nous avons là-bas. Pas avec tout, mais avec le bon:


  • lib/ - Selon les principes de pub (gestionnaire de paquets de Dart), tout le code se trouve dans ce sous-dossier;
  • pubspec.yml - c'est là que les dépendances de l'application sont écrites que vous devez installer pour l'exécuter, tout comme package.json , mais il y a une nuance, vous devez les installer non pas via l'utilitaire Dart standard mentionné ci-dessus, mais via la commande Flutter: flutter pub get <package_name> ;
  • test/ - savez-vous ce qu'il y a? Vous pouvez les exécuter en appelant flutter test ;
  • Dossiers ios/ & android/ - avec des paramètres pour chaque plate-forme, il indique les droits nécessaires pour exécuter l'application (accès à l'emplacement, Bluetooth), les icônes et tout ce qui est spécifique à la plate-forme.

Nous avons compris la structure, allez dans le dossier lib/ où le fichier main.dart nous attend. Comme vous pouvez le deviner, il s'agit du même fichier dans lequel nous devons exécuter notre application. Et cela commence comme en C (et même des tonnes d'autres) en appelant la fonction main() .


À propos des widgets (Hello World ici)


Dans Flutter, tout est construit sur Widget : il y a des vues, des styles avec des thèmes et des états dans les widgets. Il existe deux principaux types de widgets: avec et sans état, mais pas encore à ce sujet. Soyons tranquilles.


Supprimez tout de main.dart . Collez le code suivant en lisant attentivement les commentaires:


 import 'package:flutter/widgets.dart'; //     //  Dart      main() main() => runApp( //   runApp  Flutter Text( //  ,   ,   <span> 'Hello, World!!!', //   —     textDirection: TextDirection.ltr, //       ), ); 

runApp(…) prend un seul argument - un widget qui sera la racine de tout le projet. Soit dit en passant, Hot-reload ne peut pas le récupérer, vous devrez donc redémarrer l'application.
Text(…) - Flutter ne peut pas simplement afficher une chaîne à l'écran. Pour afficher du texte, vous devez spécifier Text . textDirection . Et ce n'est pas l'alignement du texte comme l'alignement du text-align , par rapport au Web, c'est un analogue de la direction . Une partie de l'API pour l'internationalisation d'une application. Text ne fonctionnera pas tant qu'il ne connaît pas la direction, mais vous n'avez pas besoin de le spécifier partout - nous analyserons ensuite comment ajuster la direction du texte pour l'ensemble de l'application.


Vous avez déjà lancé l'application? "Bonjour tout le monde!" dehors! Il semble que ce soit ... Oui? Mais quelque chose s'est manifestement mal passé.


Capture d'écran de l'application en cours d'exécution


Le texte est bloqué par les informations système. Nous avons tout l'espace d'écran à notre disposition, et nous avons sorti le widget à son tout début, où, entre autres, les informations système sont affichées. Essayons de déplacer notre texte quelque part.


 import 'package:flutter/widgets.dart'; main() => runApp( Center( // ,      child: Text( 'Hello, World!', textDirection: TextDirection.ltr, ), ), ); 

Center(…) est un widget qui vous permet de placer un autre widget passé dans l'argument child au centre horizontalement et verticalement. Vous verrez souvent des child et des children dans les applications Flutter, car presque tous les widgets utilisent ces noms pour transmettre des widgets qui doivent être dessinés à l'intérieur du widget appelé.


Les compositions de widgets sont utilisées dans Flutter pour rendre l'interface utilisateur, changer l'apparence et même transférer des données. Par exemple, le widget Directionality(…) définit la direction du texte pour tous les widgets enfants:


 import 'package:flutter/widgets.dart'; main() => runApp( Directionality( textDirection: TextDirection.ltr, child: Center( child: Text('Hello, World!'), ), ), ); 

Regardons un autre widget très important et transformons en même temps l'apparence de notre application:


 import 'package:flutter/widgets.dart'; main() => runApp( Directionality( textDirection: TextDirection.ltr, child: Container( //  ! <div>   Flutter' //   Container  color    color: Color(0xFF444444), child: Center( child: Text( 'Hello, World!', style: TextStyle( //     ,    color: Color(0xFFFD620A), //     fontSize: 32.0, //    ), ), ), ), ), ); 

Capture d'écran de l'application HelloWorld


Color(…) - couleur. La documentation indique différentes façons de le définir, mais l'essentiel est simplement de passer le numéro au constructeur de classe. Dans l'exemple ci-dessus, nous transmettons au constructeur un nombre écrit sous forme hexadécimale, qui est très similaire à HEX, seulement au début, nous avons ajouté deux caractères supplémentaires indiquant le degré de transparence de la couleur, où 0x00 est absolument transparent et 0xFF n'est pas du tout transparent.


TextStyle(…) - un widget encore plus intéressant, avec lui, vous pouvez définir la couleur, la taille, l'épaisseur, l'espacement des lignes, ajouter du soulignement et plus encore.


Application Flutter écrite, c'est fait! Sur les quais, vous pouvez lire comment l'assembler pour Android et iOS , il y a des liens au même endroit pour vous dire comment l'envoyer au magasin souhaité. À qui cela ne suffit pas, j'ai jeté quelques lignes supplémentaires sur Flutter, peut-être plus ...


Widgets sans état Pro


Comment utiliser les widgets - nous avons compris, voyons maintenant comment les créer. Il a déjà été mentionné ci-dessus qu'il existe des widgets qui ont un état et qui ne l'ont pas. Jusqu'à présent, nous n'avons utilisé que des widgets sans état. Cela ne signifie pas qu'ils ne l'ont pas du tout, car les widgets ne sont que des classes et leurs propriétés peuvent être modifiées. Juste après le rendu du widget, la modification de son état n'entraînera pas la mise à jour de ce widget dans l'interface utilisateur. Par exemple, si nous devons changer le texte à l'écran, nous devrons générer un autre widget Text et spécifier le nouveau contenu que nous voulons afficher. Ces widgets peuvent être appelés constants, si vous voyez ce que je veux dire. Et ils sont simples, alors commençons par eux.


Pour créer un widget sans état, vous avez besoin de:


  1. Trouvez un beau nom pour la nouvelle classe;
  2. Héritez une classe de StatelessWidget ;
  3. Implémentez une méthode build() qui prend un BuildContext comme argument et retourne une sorte de Widget .

 import 'package:flutter/widgets.dart'; main() => runApp( Directionality( textDirection: TextDirection.ltr, child: Center( child: MyStatelessWidget() ), ), ); class MyStatelessWidget extends StatelessWidget { //  @override   ,    , //         //  ,       @override Widget build(BuildContext context) { // [context]    return Text('Hello!'); } } 

Exemple de widget avec un argument:


 // … class MyStatelessWidget extends StatelessWidget { //   Stateless      final,   const final String name; //   MyStatelessWidget(this.name); //   @override Widget build(BuildContext context) { // [context]     return Text('Hello, $name!'); } } 

A propos de Stateless plus et rien à ajouter ...


À propos du rechargement à chaud


Veuillez noter que lorsque vous modifiez le contenu de notre widget, l'application sera automatiquement redessinée. Après avoir supprimé le widget de la fonction main() , le rechargement à chaud a commencé à nous aider.


Il est également important de comprendre qu'en raison du module lancé pour l'échange à chaud, l'application s'exécute un ordre de grandeur plus lentement.


À propos de GestureDetector


Widget GestureDetector en action


Dans la section suivante, nous traiterons de StatefulWidget (avec des widgets qui changent lorsque leur état change). Pour que cela soit intéressant, nous devons en quelque sorte changer cet état, d'accord? Nous allons changer l'état du widget en réponse aux touches sur l'écran. Pour ce faire, nous utiliserons le GestureDetector(…) - un widget qui ne dessine rien, mais surveille les touches sur l'écran du smartphone et signale à ce sujet les fonctions qui lui sont transférées.


Créez un bouton au centre de l'écran, lorsque vous cliquez dessus, un message s'affiche dans la console:


 import 'package:flutter/widgets.dart'; main() => runApp( Directionality( textDirection: TextDirection.ltr, child: Container( color: Color(0xFFFFFFFF), child: App(), ), ), ); class App extends StatelessWidget { @override Widget build(BuildContext context) { return Center( child: GestureDetector( //     onTap: () { //    GestureDetector //    ,      print('You pressed me'); }, child: Container( //     decoration: BoxDecoration( //   shape: BoxShape.circle, //     color: Color(0xFF17A2B8), //      ), width: 80.0, height: 80.0, ), ), ); } } 

Cliquez sur le bouton bleu et voyez le message dans la console. On clique encore et encore on voit le message dans la console. Encore une fois ... D'accord, arrête de coller.


Widgets avec état


StatefulWidget - Simple, encore plus simple que StatelessWidget . Mais il y a une nuance: ils n'existent pas par eux-mêmes, pour leur travail nous avons besoin d'une autre classe qui stockera l'état de ce widget. En même temps, sa partie visuelle (les widgets dont elle est constituée) devient également son état.


Pour commencer, regardez la classe des widgets:


 // … class Counter extends StatefulWidget { //      ,     , //   createState() @override State<Counter> createState() => _CounterState(); //        State, //   State<> } 

Ci-dessus, nous avons créé un widget «vide» qui implémentait une méthode createState() très simple. Cette séparation de la présentation et de l'état permet à Flutter d'optimiser considérablement l'application.


L'objet d'état est complètement simple. De plus, il est presque identique à celui de StatelessWidget écrit par nous ci-dessus. Sa principale différence est la classe parente.


 // … class _CounterState extends State<Counter> { //    -    , //      . //   ,     int counter = 0; //     ,       //   ,      Stateless . @override Widget build(BuildContext context) { //          , //     —  : return Center( child: GestureDetector( onTap: () { //  ,   ,    //  counter. setState(() { // setState()   ,    //      ,    ++counter; }); }, child: Container( decoration: BoxDecoration( shape: BoxShape.circle, color: Color(0xFF17A2B8), ), width: 80.0, child: Center( child: Text( //    counter '$counter', //      style: TextStyle(fontSize: 30.0), ), ), ), ), ); } } 

Exécution d'une application de compteur


Notez que le nom de classe commence par un trait de soulignement inférieur. Dans Dart, tous les noms commençant par des traits de soulignement identifient des valeurs privées. Et l'état des widgets dans Flutter est généralement laissé privé, bien que cela ne soit pas nécessaire.


Quelle merveilleuse application nous avons faite! C'est un excellent résultat. Mais avant de terminer cette partie du cours, regardons quelques widgets plus intéressants. Seulement cette fois, nous écrirons plus de code, juste pour le rendre plus intéressant. La plupart des applications devraient vous être familières, et le reste vous devriez avoir déjà appris à comprendre:


 import 'package:flutter/widgets.dart'; main() => runApp(App()); class App extends StatelessWidget { @override Widget build(BuildContext context) { return Directionality( textDirection: TextDirection.ltr, child: Container( padding: EdgeInsets.symmetric( vertical: 60.0, horizontal: 20.0, ), color: Color(0xFFFFFFFF), child: Content(), ), ); } } class Content extends StatelessWidget { @override Widget build(BuildContext context) { return Column( children: [ Counter('Manchester United'), Counter('Juventus'), ], ); } } class Counter extends StatefulWidget { final String _name; Counter(this._name); @override State<Counter> createState() => _CounterState(); } class _CounterState extends State<Counter> { int count = 0; @override Widget build(BuildContext context) { return Container( margin: EdgeInsets.only(bottom: 10.0), padding: EdgeInsets.all(4.0), decoration: BoxDecoration( border: Border.all(color: Color(0xFFFD6A02)), borderRadius: BorderRadius.circular(4.0), ), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ // widget —    State,    //      ,      _CounterLabel(widget._name), _CounterButton( count, onPressed: () { setState(() { ++count; }); }, ), ], ), ); } } class _CounterLabel extends StatelessWidget { static const textStyle = TextStyle( color: Color(0xFF000000), fontSize: 26.0, ); final String _label; _CounterLabel(this._label); @override Widget build(BuildContext context) { return Text( _label, style: _CounterLabel.textStyle, ); } } class _CounterButton extends StatelessWidget { final _count; final _onPressed; _CounterButton(this._count, {@required this._onPressed}); @override Widget build(BuildContext context) { return GestureDetector( onTap: () { _onPressed(); }, child: Container( padding: EdgeInsets.symmetric(horizontal: 6.0), decoration: BoxDecoration( color: Color(0xFFFD6A02), borderRadius: BorderRadius.circular(4.0), ), child: Center( child: Text( '$_count', style: TextStyle(fontSize: 20.0), ), ), ), ); } } 

Une autre application de compteur sur Flutter


Nous avons deux nouveaux widgets: Column() et Row() . Essayez de comprendre ce qu'ils font. Et dans le prochain article, nous les examinerons plus en détail, ainsi que regarder plus d'un widget qui vous permet de composer d'autres widgets ensemble, et de créer une belle application en utilisant la bibliothèque Flutter appelée Material.


À propos des devoirs


Si vous souhaitez lire autre chose à votre guise, voici une liste de liens intéressants:


Source: https://habr.com/ru/post/fr430918/


All Articles