Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Les Widgets en Flutter

Les Widgets en Flutter

Edouard Marquez

June 14, 2019
Tweet

More Decks by Edouard Marquez

Other Decks in Programming

Transcript

  1. Les Widgets en Flutter Devfest Lille 2019 En résumé, qu'est-ce

    que Flutter ? Framework permettant de concevoir des applications multiplateforme Smartphones Android et iOS Ordinateurs* Windows, Mac, Linux Embarqué Ex : Nest Hub Max Web* “ “
  2. Les Widgets en Flutter Devfest Lille 2019 Comment fonctionne Flutter

    ? Code natif Canvas Evénements Application Plateforme Position GPS Bluetooth Audio Capteurs Caméra Etc Services Widgets, Rendu Platform Channels
  3. Les Widgets en Flutter Devfest Lille 2019 La stack Flutter

    Material Cupertino Widgets Rendering Fondation Animation Painting Gestures Framework (Dart) Skia Dart Text Engine (C++)
  4. Les Widgets en Flutter Devfest Lille 2019 Du multiplateforme… mais

    natif et surtout pratique ! Dart Connait une deuxième vie grâce à Flutter Mode AOT Génération d'un binaire optimisé pour la plateforme Mode JIT Lors du développement, injection des changements à la volée Garbage collector Optimisé pour le recyclage de nombreux petits objets
  5. void main() => runApp(MyApp()); class MyApp extends StatelessWidget { @override

    Widget build(BuildContext context) { return MaterialApp( title: 'Flutter Demo', theme: ThemeData( primarySwatch: Colors.blue, ), home: MyHomePage(title: 'Flutter Demo Home Page'), ); } }
  6. void main() => runApp(MyApp()); class MyApp extends StatelessWidget { @override

    Widget build(BuildContext context) { return MaterialApp( title: 'Flutter Demo', theme: ThemeData( primarySwatch: Colors.blue, ), home: MyHomePage(title: 'Flutter Demo Home Page'), ); } }
  7. void main() => runApp(MyApp()); class MyApp extends StatelessWidget { @override

    Widget build(BuildContext context) { return MaterialApp( title: 'Flutter Demo', theme: ThemeData( primarySwatch: Colors.blue, ), home: MyHomePage(title: 'Flutter Demo Home Page'), ); } }
  8. void main() => runApp(MyApp()); class MyApp extends StatelessWidget { @override

    Widget build(BuildContext context) { return MaterialApp( title: 'Flutter Demo', theme: ThemeData( primarySwatch: Colors.blue, ), home: MyHomePage(title: 'Flutter Demo Home Page'), ); } }
  9. 1 Il en existe de toutes les formes 2 Une

    brique peut avoir plusieurs couleurs
  10. 1 Il en existe de toutes les formes 3 Une

    brique n'a qu'une seule fonction 2 Une brique peut avoir plusieurs couleurs
  11. 1 Il en existe de toutes les formes 4 On

    peut imbriquer une forme 
 dans une autre 2 Une brique peut avoir plusieurs couleurs 3 Une brique n'a qu'une seule fonction
  12. 1 Il en existe de toutes les formes 4 On

    peut imbriquer une forme 
 dans une autre 5 Ou au contraire… 
 certaines ne peuvent pas 2 Une brique peut avoir plusieurs couleurs 3 Une brique n'a qu'une seule fonction
  13. 1 Il en existe de toutes les formes 4 On

    peut imbriquer une forme 
 dans une autre 5 Ou au contraire… 
 certaines ne peuvent pas 6 On peut obtenir des résultats complexes 2 Une brique peut avoir plusieurs couleurs 3 Une brique n'a qu'une seule fonction
  14. 1 Il en existe de toutes les formes 2 Une

    brique peut avoir plusieurs couleurs 3 Une brique n'a qu'une seule fonction 4 On peut imbriquer une forme 
 dans une autre 5 Ou au contraire… 
 certaines ne peuvent pas 6 On peut obtenir des résultats complexes 7 Certaines briques sont utilitaires, d'autres visibles
  15. 1 Il existe de très nombreux Widgets Application Layout Widget

    1 Widget 2 Widget 3 Stocker des informations { "User":"toto", "Password":"LOL" } Accessibilité Image d'un pont Texte Hello World ! Animation A B
  16. Texte Hello World ! Le texte peut changer sa police

    Le texte peut changer sa couleur Le texte peut changer sa taille Le texte peut changer son alignement 2 Un Widget peut contenir des attributs
  17. Texte Hello World ! Ne sait pas gérer le padding

    Ne sait pas la couleur d'arrière-plan Ne sait pas comment gérer l'opacité Ne sait pas comment scroller… 3 Mais un Widget est ultra-spécialisé
  18. 4 On peut imbriquer un Widget dans un autre Layout

    Widget 1 Widget 2 Widget 3 Le Widget Column peut accueillir plusieurs enfants qu'il alignera les uns en dessous des autres Padding Le Widget Padding peut accueillir une seul enfant sur lequel il appliquera des marges Hello World !
  19. 7 Certains Widgets ne dessinent rien à l'écran Layout Widget

    1 Widget 2 Widget 3 Stocker des informations { "User":"toto", "Password":"LOL" } Accessibilité Image d'un pont Texte Hello World !
  20. Les Widgets en Flutter Devfest Lille 2019 Un Widget en

    Flutter est donc… Description d'une partie de la UI Peut s'imbriquer à d'autres Widgets Fait partie d'un arbre de Widgets
  21. Analytics Want to see about : Audience 260 Total Posts

    26.84% 2.648 Followers 26.32% 768 Followers 0.86% 82.6% Engagement 8.64%
  22. Les Widgets en Flutter Devfest Lille 2019 Imbriquer des Widgets

    grâce au StatelessWidget 260 Total Posts 26.84% Container Column (÷) Icon Text Text Row (㲗) Icon Text
  23. class TotalPosts extends StatelessWidget { @override Widget build(BuildContext context) {

    return Container( decoration: ShapeDecoration(shape: RoundedRectangleBorder()), child: Column(children: <Widget>[ Icon(Icons.photo_album), Text('260'), Text('Total posts'), Row(children: <Widget>[ Icon(Icons.trending_up), Text('26.84%') ]), ]), ); } }
  24. class TotalPosts extends StatelessWidget { @override Widget build(BuildContext context) {

    return Container( decoration: ShapeDecoration(shape: RoundedRectangleBorder()), child: Column(children: <Widget>[ Icon(Icons.photo_album), Text('260'), Text('Total posts'), Row(children: <Widget>[ Icon(Icons.trending_up), Text('26.84%') ]), ]), ); } }
  25. Les Widgets en Flutter Devfest Lille 2019 Gérer l'état d'un

    Widget Un Widget est immutable On va lui associer un objet State On utilise un StatefulWidget Il faut appeler la méthode setState pour indiquer que l'état a changé et qu'il faut redessiner
  26. class TotalPosts extends StatelessWidget { @override Widget build(BuildContext context) {

    return Container( decoration: ShapeDecoration(shape: RoundedRectangleBorder()), child: Column(children: <Widget>[ Icon(Icons.photo_album), Text('260'), Text('Total posts'), Row(children: <Widget>[ Icon(Icons.trending_up), Text('26.84%') ]), ]), ); } }
  27. class _TotalPostsState extends State<TotalPosts> { int posts = 260; @override

    Widget build(BuildContext context) { return Container( decoration: ShapeDecoration(shape: RoundedRectangleBorder()), child: Column(children: <Widget>[ Icon(Icons.photo_album), Text('260'), Text('Total posts'), Row(children: <Widget>[ Icon(Icons.trending_up), Text('26.84%') ]), ]), ); } }
  28. class _TotalPostsState extends State<TotalPosts> { int posts = 260; @override

    Widget build(BuildContext context) { return Container( decoration: ShapeDecoration(shape: RoundedRectangleBorder()), child: Column(children: <Widget>[ Icon(Icons.photo_album), Text('260'), Text('Total posts'), Row(children: <Widget>[ Icon(Icons.trending_up), Text('26.84%') ]), ]), ); } }
  29. class _TotalPostsState extends State<TotalPosts> { int posts = 260; @override

    Widget build(BuildContext context) { return Container( decoration: ShapeDecoration(shape: RoundedRectangleBorder()), child: Column(children: <Widget>[ Icon(Icons.photo_album), Text(posts.toString()), Text('Total posts'), Row(children: <Widget>[ Icon(Icons.trending_up), Text('26.84%') ]), ]), ); } }
  30. class _TotalPostsState extends State<TotalPosts> { int posts = 260; @override

    Widget build(BuildContext context) { return InkWell( onTap: () { setState(() { posts++; }); }, child: Container( child: Column(children: <Widget>[ // Même contenu ]) ), ); } }
  31. class _TotalPostsState extends State<TotalPosts> { int posts = 260; @override

    Widget build(BuildContext context) { return InkWell( onTap: () { setState(() { posts++; }); }, child: Container( child: Column(children: <Widget>[ // Même contenu ]) ), ); } }
  32. Les Widgets en Flutter Devfest Lille 2019 Les Widgets ont

    aussi quelques particularités… Une instance est immutable L'arbre est aussi immutable Ne connaît pas sa taille Ne connaît pas sa position à l'écran Ne connaît pas ses voisins Ne sait pas dessiner à l'écran
  33. Les Widgets en Flutter Devfest Lille 2019 La création du

    couple Widget/Element 1 Instancier le Widget 2 Créer un Element 3 Associer les deux 4 Et on fait cela pour tous les Widget(s) Widget Element Widget Element Widget Element Arbre des widgets Arbre des éléments
  34. class TotalPosts extends StatelessWidget { @override Widget build(BuildContext context) {

    return Container( decoration: ShapeDecoration(shape: RoundedRectangleBorder()), child: Column(children: <Widget>[ Icon(Icons.photo_album), Text('260'), Text('Total posts'), Row(children: <Widget>[ Icon(Icons.trending_up), Text('26.84%') ]), ]), ); } }
  35. Les objets BuildContext sont en réalité des objets de type

    Element. L'interface BuildContext est utilisée pour éviter la manipulation directe d'un Element. “ “
  36. Les Widgets en Flutter Devfest Lille 2019 Un exemple de

    InheritedWidget Thème de l'application La recherche se fait grâce au BuildContext “ “ Le père fournit : Le fils appelle : .accentColor Theme.of(context)
  37. class FrogColor extends InheritedWidget { const FrogColor({ Key key, @required

    this.color, @required Widget child, }) : assert(color != null), assert(child != null), super(key: key, child: child); final Color color; static FrogColor of(BuildContext context) { return context.inheritFromWidgetOfExactType(FrogColor) as FrogColor; } @override bool updateShouldNotify(FrogColor old) => color != old.color; }
  38. class FrogColor extends InheritedWidget { const FrogColor({ Key key, @required

    this.color, @required Widget child, }) : assert(color != null), assert(child != null), super(key: key, child: child); final Color color; static FrogColor of(BuildContext context) { return context.inheritFromWidgetOfExactType(FrogColor) as FrogColor; } @override bool updateShouldNotify(FrogColor old) => color != old.color; }
  39. class FrogColor extends InheritedWidget { const FrogColor({ Key key, @required

    this.color, @required Widget child, }) : assert(color != null), assert(child != null), super(key: key, child: child); final Color color; static FrogColor of(BuildContext context) { return context.inheritFromWidgetOfExactType(FrogColor) as FrogColor; } @override bool updateShouldNotify(FrogColor old) => color != old.color; }
  40. class FrogColor extends InheritedWidget { const FrogColor({ Key key, @required

    this.color, @required Widget child, }) : assert(color != null), assert(child != null), super(key: key, child: child); final Color color; static FrogColor of(BuildContext context) { return context.inheritFromWidgetOfExactType(FrogColor) as FrogColor; } @override bool updateShouldNotify(FrogColor old) => color != old.color; }
  41. Les Widgets en Flutter Devfest Lille 2019 Rappel sur les

    Widgets… Un Widget est immutable Ne connaît pas sa taille Ne connaît pas sa position à l'écran Ne connaît pas ses voisins Ne sait pas dessiner à l'écran
  42. Les Widgets en Flutter Devfest Lille 2019 Un RenderObject a

    trois rôles Gestion de l'agencement et de la taille (layout) Dessin à l'écran Gestion de l'interaction (hit testing)
  43. Les Widgets en Flutter Devfest Lille 2019 Non pas deux,

    mais trois arbres Arbre des éléments Arbre mutable qui fait le lien entre un Widget et son RenderObject Arbre de widgets Arbre immutable qui décrit les composants et leurs valeurs Arbre de rendu Arbre mutable de RenderObjects qui s'occupe de gérer le layout, le dessin et le touch
  44. Arbre des widgets Arbre des éléments Arbre de rendu RenderObjectWidget

    RenderObjectWidget Theme Element Element RenderObject Element RenderObject
  45. Les Widgets en Flutter Devfest Lille 2019 Objectif accompli Décrire/déclarer

    notre UI Gérer l'état des Widgets Gérer le rendu d'un Widget
  46. Arbre des widgets Arbre des éléments Evénements 1 On affiche

    un Widget Text('Hello') Element 2 On modifie le texte pour "Hello world" Element Element Text('Hello World') Element Text('Hello World')
  47. Arbre des widgets Arbre des éléments Evénements 1 On affiche

    un texte "Hello" Text('Hello') Element 2 On remplace par un autre Widget Element Element Image() Image() Element Image()
  48. Créer une classe avec const renvoie la même instance “

    “ new Text("a") new Text("b") new Text("a") new Text("a") const Text("a") const Text("a") const Text("a") const Text("b")
  49. Arbre des widgets Arbre des éléments Evénements 1 On affiche

    un texte const("Hello") const Text('Hello') Element 2 On modifie le texte pour "Hello world" Element Element const Text('Hello')
  50. Les Widgets en Flutter Devfest Lille 2019 Cela peut paraître

    compliqué… Arbre des éléments Arbre mutable qui fait le lien entre un Widget et son RenderObject Arbre de widgets Arbre qui décrit les composants et leurs valeurs Arbre de rendu Arbre mutable de RenderObjects qui s'occupent de gérer le layout, le dessin et le touch