Pour appeler une fonction d'un parent, vous pouvez utiliser le schéma de rappel. Dans cet exemple, une fonction (onColorSelected
) est passée à l'enfant. L'enfant appelle la fonction lorsqu'un bouton est pressé :
import 'package:flutter/material.dart';
class Parent extends StatefulWidget {
@override
State createState() {
return ParentState();
}
}
class ParentState extends State {
Color selectedColor = Colors.grey;
@override
Widget build(BuildContext context) {
return Column(
children: [
Container(
color: selectedColor,
height: 200.0,
),
ColorPicker(
onColorSelect: (Color color) {
setState(() {
selectedColor = color;
});
},
)
],
);
}
}
class ColorPicker extends StatelessWidget {
const ColorPicker({this.onColorSelect});
final ColorCallback onColorSelect;
@override
Widget build(BuildContext context) {
return Row(
children: [
RaisedButton(
child: Text('rouge'),
color: Colors.red,
onPressed: () {
onColorSelect(Colors.red);
},
),
RaisedButton(
child: Text('vert'),
color: Colors.green,
onPressed: () {
onColorSelect(Colors.green);
},
),
RaisedButton(
child: Text('bleu'),
color: Colors.blue,
onPressed: () {
onColorSelect(Colors.blue);
},
)
],
);
}
}
typedef ColorCallback = void Function(Color color);
Les widgets internes de Flutter comme les boutons ou les champs de formulaire utilisent exactement le même schéma. Si vous voulez simplement appeler une fonction sans arguments, vous pouvez utiliser le type VoidCallback
au lieu de définir votre propre type de rappel.
Si vous souhaitez notifier un parent plus haut, vous pouvez simplement répéter ce schéma à chaque niveau de hiérarchie :
class ColorPickerWrapper extends StatelessWidget {
const ColorPickerWrapper({this.onColorSelect});
final ColorCallback onColorSelect;
@override
Widget build(BuildContext context) {
return Padding(
padding: EdgeInsets.all(20.0),
child: ColorPicker(onColorSelect: onColorSelect),
)
}
}
Appeler une méthode d'un widget enfant à partir d'un widget parent est déconseillé dans Flutter. À la place, Flutter vous encourage à transmettre l'état d'un enfant en tant que paramètres de constructeur. Au lieu d'appeler une méthode de l'enfant, vous appelez simplement setState
dans le widget parent pour mettre à jour ses enfants.
Une approche alternative sont les classes controller
dans Flutter (ScrollController
, AnimationController
, ...). Celles-ci sont également passées aux enfants en tant que paramètres de constructeur, et elles contiennent des méthodes pour contrôler l'état de l'enfant sans appeler setState
sur le parent. Exemple:
scrollController.animateTo(200.0, duration: Duration(seconds: 1), curve: Curves.easeInOut);
Les enfants doivent alors écouter ces changements pour mettre à jour leur état interne. Bien sûr, vous pouvez également implémenter votre propre classe de contrôleur. Si nécessaire, je vous recommande de consulter le code source de Flutter pour comprendre comment cela fonctionne.
Les futurs et les flux sont une autre alternative pour transmettre l'état, et pourraient également être utilisés pour appeler une fonction d'un enfant.
Mais je ne le recommande vraiment pas. Si vous devez appeler une méthode d'un widget enfant, il est très probable que l'architecture de votre application est défectueuse. Essayez de remonter l'état jusqu'à l'ancêtre commun !
0 votes
Peut-être un doublon de Déclencher une fonction à partir d'un widget vers un objet State
0 votes
Si vous pouvez vous assurer qu'un widget est un descendant d'un autre, vous pouvez utiliser InheritedWidget.
0 votes
@JacobPhillips Utilisez simplement
context.ancestorStateOfType
dans cette situation.0 votes
@RémiRousselet J'ai juste besoin d'un peu plus d'aide ici, j'essaie d'envoyer des données d'un widget enfant à un widget parent et tous les exemples de stream et listenable font l'inverse et c'est exactement mon problème. Je veux appeler une fonction d'un widget enfant à un widget parent, désolé de ne pas l'avoir mentionné ci-dessus.
1 votes
Transmettez l'intégralité du
StreamController
à votre enfant au lieu de simplementStream
si votre enfant doit également soumettre des événements.