web-dev-qa-db-fra.com

Quelqu'un peut-il m'expliquer ce que fait la classe Builder dans Flutter?

La documentation est très confuse et vague. Voici ce qu'il dit:

classe Builder

Un widget platonique qui appelle une fermeture pour obtenir son widget enfant.

Voici mes questions:

  1. Que veulent-ils dire par "platonique"?
  2. Qu'entendent-ils par "fermeture"?
  3. Quel est exactement le but de cette classe?
14
Walter M

Après de longues heures de recherches poussées sur Internet, j'ai rassemblé de petits extraits et les ai combinés pour mettre une explication cohérente et claire de ce que fait la classe Builder.

Terminologie:

Selon la documentation officielle de flutter, la classe de constructeur est définie comme suit:

Un widget platonique qui appelle une fermeture pour obtenir son widget enfant.

Platonique signifie la chose la plus simple possible de ce genre. Le terme fermeture n'est qu'un autre nom pour une fonction lambda .

Objectif:

Cela va être une longue explication, mais soyez indulgent avec moi:

Dans le framework Flutter, chaque widget a une méthode build qui accepte un paramètre BuildContext :

Construction de widgets (contexte BuildContext) {...}

Nous devons nous rappeler que le contexte objet est passé à la fonction build du widget automatiquement par le cadre. Puisque le framework s'occupe de cela automatiquement, il n'y a aucune raison pour qu'un widget ait un constructeur ou une fonction (à part build) qui devrait accepter un contexte paramètre.

Par conséquent, si vous essayez de transmettre un objet contextuel spécifique à un enfant, vous ne pourrez pas le faire. Vous ne pouvez pas appeler build () et passer manuellement votre propre objet de contexte . Je veux dire, vous pouvez, mais vous appelleriez la fonction de construction deux fois:

  1. Votre appel manuel.
  2. L'appel automatique par le framework.

Alors, comment pouvons-nous passer un contexte spécifique? C'est là qu'intervient la classe Builder. Le but de la classe Builder est simplement de construire et de renvoyer des widgets enfants. En quoi est-ce différent de tout autre widget? Aha! La classe Builder vous permet de transmettre un objet context spécifique à ses enfants. La classe Builder est fondamentalement votre propre fonction de construction que vous configurez.

Pourquoi devrais-je passer un objet contextuel spécifique? Voyons un exemple:

Disons que nous voulons ajouter un nouveau SnackBar widget à son nouveau échafaudage widget parent renvoyé:

 @override
  Widget build(BuildContext context) {
    return new Scaffold(
        appBar: new AppBar(
          title: new Text(widget.title),
        ),
        body: new Container(),
        /// Scaffold doesn't exist in this context here
        /// because the context thats passed into 'build'
        /// refers to the Widget 'above' this one in the tree,
        /// and the Scaffold doesn't exist above this exact build method
        ///
        /// This will throw an error:
        /// 'Scaffold.of() called with a context that does not contain a Scaffold.'
        floatingActionButton: new FloatingActionButton(onPressed: () {
          Scaffold.of(context).showSnackBar(
                new SnackBar(
                  content: new Text('SnackBar'),
                ),
              );
        }));
  }

Ce code ci-dessus ne fonctionne pas. La fonction Scaffold.of (context) ne trouvera pas l'échafaudage car :

  1. Le widget Scaffold n'a pas encore été créé.
  2. L'objet contextuel qui a été transmis à la fonction de génération fait référence au widget parent, qui n'est pas un échafaudage widget.

Alors, comment donner au widget Childr SnackBar l'accès au widget parent Scaffold ? Nous utilisons une classe Builder pour passer le contexte du widget Scaffold :

 @override
  Widget build(BuildContext context) {
    return new Scaffold(
      appBar: new AppBar(
        title: new Text(widget.title),
      ),
      body: new Container(),
      /// Builders let you pass context
      /// from your *current* build method
      /// Directly to children returned in this build method
      ///
      /// The 'builder' property accepts a callback
      /// which can be treated exactly as a 'build' method on any
      /// widget
      floatingActionButton: new Builder(builder: (BuildContext context) {
        return new FloatingActionButton(onPressed: () {
          Scaffold.of(context).showSnackBar(
                new SnackBar(
                  backgroundColor: Colors.blue,
                  content: new Text('SnackBar'),
                ),
              );
        });
      }),
    );
  }

Rappelez-vous, le constructeur de classe Builder:

Builder ({Key key, @required WidgetBuilder builder})

crée un widget en déléguant sa construction à la fonction de rappel passée par son constructeur.

Donc, dans le code:

new Builder(builder: (BuildContext context){ ... });

nous avons fourni une fermeture qui:

  1. Contient un paramètre Contexte BuildContext
  2. Génère et renvoie des widgets enfants basés sur ce contexte transmis.

Fondamentalement, vous avez fourni votre propre fonction de génération. Le paramètre Contexte BuildContext dans cette fermeture est le contexte de l'échafaudage! Baboom!

C'est essentiellement ça. La documentation Flutter ne fournit aucune explication approfondie à ce sujet. Je sens que j'aurais plus de facilité à déchiffrer les anciens hiéroglyphes qu'à décoder la documentation Flutter.

J'espère que cela aidera toute personne qui est actuellement sur son chemin fastidieux dans l'apprentissage de Flutter.

39
Walter M

Il convertit essentiellement une fonction qui construit un widget en widget.

Wo où vous devez passer un widget mais seulement avoir une fonction qui renvoie un widget, vous pouvez utiliser le widget Builder.

bool bar;

Widget createFooOrBarWidget() {
  if(bar) {
    return BarWidget();
  } 
  return FooWidget();
}

Widget build(BuildContext context) =>
  Container(child: Builder((context) => createFooOrBarWidget()));

vous pouvez également utiliser

Widget build(BuildContext context) =>
  Container(child: createFooOrBarWidget());

mais le premier retarde la création du widget Foo ou Bar jusqu'à ce que build soit réellement appelé.

8
Günter Zöchbauer