Que fait BuildContext
et quelles informations en tirons-nous?
https://docs.flutter.io/flutter/widgets/BuildContext-class.html n'est tout simplement pas clair.
https://flutter.io/widgets-intro/#basic-widgets à la 9ème instance du terme BuildContext
, il y a un exemple, mais son utilisation n'est pas claire. Cela fait partie d'un ensemble de code beaucoup plus vaste qui me perd, et j'ai donc du mal à comprendre ce que BuildContext
est.
Quelqu'un peut-il expliquer cela en termes simples/très basiques?
BuildContext
est, comme son nom l'indique, le contexte dans lequel un widget spécifique est construit.
Si vous avez déjà fait un peu de React auparavant, ce contexte est en quelque sorte similaire au contexte de React (mais beaucoup plus simple à utiliser); avec quelques bonus.
De manière générale, il y a 2 cas d'utilisation pour le contexte:
Le deuxième point est plutôt rare. Par contre, le premier point est utilisé presque partout.
Par exemple, lorsque vous souhaitez définir un nouvel itinéraire, vous exécuterez Navigator.of(context).pushNamed('myRoute')
.
Notez le contexte ici. Il sera utilisé pour obtenir l'instance la plus proche du widget NavigatorState
ci-dessus dans l'arborescence. Appelez ensuite la méthode pushNamed
sur cette instance.
Cool, mais quandIveux-t-il l'utiliser?
BuildContext est vraiment utile lorsque vous souhaitez transmettre des données vers le bas sans devoir les attribuer manuellement à tous les widgets. Configurations par exemple; vous aurez envie d'y accéder partout. Mais vous ne voulez pas le transmettre à chaque constructeur.
Vous pourriez potentiellement faire un global ou un singleton; mais lorsque les confs changent, vos widgets ne seront pas automatiquement reconstruits.
Dans ce cas, vous utilisez InheritedWidget
. Avec cela, vous pourriez potentiellement écrire ce qui suit:
class Configuration extends InheritedWidget {
final String myConf;
const Configuration({this.myConf, Widget child}): super(child: child);
@override
bool updateShouldNotify(Configuration oldWidget) {
return myConf != oldWidget.myConf;
}
}
Et puis, utilisez-le de cette façon:
void main() {
runApp(
new Configuration(
myConf: "Hello world",
child: new MaterialApp(
// usual stuff here
),
),
);
}
Grâce à cela, maintenant partout dans votre application, vous pouvez accéder à ces configurations à l'aide de la variable BuildContext
. En faisant
final configuration = context.inheritFromWidgetOfExactType(Configuration);
Et ce qui est encore plus cool, c’est que les widgets tous qui appellent inheritFromWidgetOfExactType(Configuration)
seront automatiquement reconstruits lorsque les configurations changeront.
Génial non?
BuildContext
Class n'est rien d'autre qu'une référence à l'emplacement d'un Widget dans l'arborescence de tous les Widgets construits.
Chaque widget Flutter a une méthode @override build()
avec l'argument BuildContext
.
class CartItemWidget extends StatelessWidget {
@override
Widget build(BuildContext context) {.....
Expliquez simplement que la BuildContext
est:
Un BuildContext n'appartient qu'à un seul widget.
Si un widget "A" a des widgets enfants, la variable BuildContext
du widget "A" deviendra le BuildContext parent des enfants directs BuildContexts
.
En lisant cela, il est clair que BuildContexts
sont chaînés et composent un arbre de BuildContexts
(relation parent-enfant)
Si nous essayons maintenant d'illustrer la notion de BuildContext dans le diagramme précédent, nous obtenons (toujours sous forme de vue très simplifiée) où chaque couleur représente un BuildContext (sauf celui de MyApp, qui est différent):
Le diagramme suivant montre (une version simplifiée de) la séquence d’actions/appels liés à la création d’un widget à état dynamique.
L'état du widget est indépendant des paramètres et pourtant, il était reconstruit à chaque fois que les paramètres changeaient. Dans ce cas, vous devez utiliser InheritedWidget
InheritedWidget
est un type spécial de widget qui définit un contexte à la racine d'un sous-arbre. Il peut efficacement fournir ce contexte à chaque widget de cette sous-arborescence. Le modèle d'accès semblerait familier aux développeurs Flutter:
class MyInheritedWidget extends InheritedWidget {
MyInheritedWidget({
Key key,
@required Widget child,
this.data,
}): super(key: key, child: child);
final data;
static MyInheritedWidget of(BuildContext context) {
return context.inheritFromWidgetOfExactType(MyInheritedWidget);
}
@override
bool updateShouldNotify(MyInheritedWidget oldWidget) => data != oldWidget.data;
}
La méthode static MyInheritedWidget of(BuildContext context)
permet à tous les widgets enfants d’obtenir l’instance de la variable MyInheritedWidget
la plus proche »qui renferme le contexte.
Enfin, la méthode updateShouldNotify
remplacée est utilisée pour indiquer à la InheritedWidget
si des notifications doivent être transmises à tous les widgets enfants (ceux enregistrés/abonnés) si une modification est appliquée aux données.
pour plus d'informations