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
    Edouard Marquez

    (Développeur freelance Flutter & Android)

    View full-size slide

  2. Avant de commencer

    View full-size slide

  3. 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*


    View full-size slide

  4. 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

    View full-size slide

  5. 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++)

    View full-size slide

  6. 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

    View full-size slide

  7. Les Widgets en Flutter Devfest Lille 2019
    Un développement agréable et rapide grâce au Hot Reload

    View full-size slide

  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'),
    );
    }
    }

    View full-size slide

  9. 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'),
    );
    }
    }

    View full-size slide

  10. Une application est un Widget


    View full-size slide

  11. 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'),
    );
    }
    }

    View full-size slide

  12. 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'),
    );
    }
    }

    View full-size slide

  13. Qui elle même
    affiche des Widgets ?


    View full-size slide

  14. Oui, en Flutter
    Tout est un Widget


    View full-size slide

  15. Les Widgets expliqués

    View full-size slide

  16. Ceci n'est pas une

    présentation sponsorisée

    View full-size slide

  17. 1 Il en existe de toutes les formes

    View full-size slide

  18. 1 Il en existe de toutes les formes
    2 Une brique peut avoir plusieurs couleurs

    View full-size slide

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

    View full-size slide

  20. 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

    View full-size slide

  21. 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

    View full-size slide

  22. 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

    View full-size slide

  23. 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

    View full-size slide

  24. Et appliqué à Flutter ?

    View full-size slide

  25. 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

    View full-size slide

  26. 1 Il existe de très nombreux Widgets
    flutter.dev

    Widgets catalog

    View full-size slide

  27. 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

    View full-size slide

  28. 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é

    View full-size slide

  29. 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 !

    View full-size slide

  30. Texte
    Hello World !
    5 Ou au contraire… certains ne peuvent pas
    Image

    View full-size slide

  31. 6 On peut obtenir des résultats complexes

    View full-size slide

  32. 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 !

    View full-size slide

  33. Si on résume

    View full-size slide

  34. 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

    View full-size slide

  35. Widget A
    Widget B
    Widget D Widget E
    Widget C
    Widget F Widget G

    View full-size slide

  36. Mise en application

    View full-size slide

  37. 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%

    View full-size slide

  38. 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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

  41. Et la gestion de l'état ?

    View full-size slide

  42. 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

    View full-size slide

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

    View full-size slide

  44. class TotalPosts extends StatefulWidget {
    @override
    _TotalPostsState createState() => _TotalPostsState();
    }

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

  50. Oui, mais…

    View full-size slide

  51. 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

    View full-size slide

  52. La notion d'Element

    View full-size slide

  53. Un widget décrit la
    configuration
    d'un Element


    View full-size slide

  54. 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

    View full-size slide

  55. Un Element désigne
    l'instanciation
    d'un Widget à un
    endroit de l'arbre


    View full-size slide

  56. Widget A
    Widget B
    Widget D Widget E
    Widget C
    Widget F Widget G

    View full-size slide

  57. Element A
    Element B
    Element D Element E
    Element C
    Element F Element G

    View full-size slide

  58. Le BuildContext ?

    View full-size slide

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

    View full-size slide

  60. 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.


    View full-size slide

  61. Communication

    View full-size slide

  62. BuildContext A
    BuildContext B BuildContext C
    BuildContext
    D
    BuildContext
    E
    BuildContext
    F
    BuildContext
    G

    View full-size slide

  63. BuildContext A
    BuildContext B BuildContext C
    BuildContext
    D
    BuildContext
    E
    BuildContext
    F
    BuildContext
    G

    View full-size slide

  64. BuildContext A
    BuildContext B BuildContext C
    BuildContext
    D
    BuildContext
    E
    BuildContext
    F
    BuildContext
    G

    View full-size slide

  65. L'Inherited Widget

    View full-size slide

  66. Propage des informations
    d'un père
    vers ses enfants


    View full-size slide

  67. 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)

    View full-size slide

  68. 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;
    }

    View full-size slide

  69. 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;
    }

    View full-size slide

  70. 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;
    }

    View full-size slide

  71. A

    FrogColor
    B
    D E
    C

    FrogColor
    F G

    View full-size slide

  72. A

    FrogColor
    B
    D E
    C

    FrogColor
    F G
    FrogColor.of(context)

    View full-size slide

  73. A

    FrogColor
    B
    D E
    C

    FrogColor
    F G

    View full-size slide

  74. A

    FrogColor
    B
    D E
    C

    FrogColor
    F G

    View full-size slide

  75. A

    FrogColor
    B
    D E
    C

    FrogColor
    F G

    View full-size slide

  76. A

    FrogColor
    B
    D E
    C

    FrogColor
    F G
    FrogColor.of(context)

    View full-size slide

  77. A

    FrogColor
    B
    D E
    C

    FrogColor
    F G

    View full-size slide

  78. Le changement

    View full-size slide

  79. 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;
    }

    View full-size slide

  80. A

    FrogColor
    B
    D E
    C
    F G

    View full-size slide

  81. A

    FrogColor
    B
    D E
    C
    F G

    View full-size slide

  82. 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

    View full-size slide

  83. Pour qu'un Widget puisse être
    dessiné, il faut lui attacher un
    RenderObject


    View full-size slide

  84. 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)

    View full-size slide

  85. 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

    View full-size slide

  86. Arbre des

    widgets
    Arbre des

    éléments
    Arbre de

    rendu
    RenderObjectWidget
    RenderObjectWidget
    Theme
    Element
    Element
    RenderObject
    Element RenderObject

    View full-size slide

  87. 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

    View full-size slide

  88. Oui, mais…

    View full-size slide

  89. Que se passe-t-il
    lors des mises à jour ?


    View full-size slide

  90. 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')

    View full-size slide

  91. 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()

    View full-size slide

  92. 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")

    View full-size slide

  93. 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')

    View full-size slide

  94. 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

    View full-size slide

  95. Merci !


    Questions ?
    @g123k @FlutterFr

    View full-size slide