web-dev-qa-db-fra.com

méthode d'appel dans un widget stateful à partir d'un autre widget stateful - Flutter

J'ai un projet de flutter sur lequel je travaille. Je ne peux pas mettre le code dans son ensemble car il contient plus de 500 lignes de code. Je vais donc essayer de poser ma question aussi simplement que si j'utilisais l'imp. section du code. 

j'ai un widget avec état et certaines fonctions à l'intérieur de celui-ci dans la classe qui s'étend étend State<MusicPlayer>

fichier lib\main.Dart

il suffit de prendre une fonction simple comme 

class MyAppState extends State<MyApp>{
...
void printSample (){
  print("Sample text");
}
...

cette fonction est à l'intérieur du widget avec état dans la classe principale. 

il y a un autre fichier lib\MyApplication.Dart

ce fichier a aussi un widget avec état puis-je faire quelque chose pour que je puisse appeler la fonction printSample() ici ..

class MyApplicationState extends State<MyApplication>{
...
@override
  Widget build(BuildContext context) {
    return new FlatButton(
      child: new Text("Print Sample Text"),
      onPressed :(){
       // i want to cal the function here how is it possible to call the 
       // function 
       // printSample()  from here??  
      }
    );
  }
...
}
7
Aman Malhotra

Pour appeler une fonction d'un parent, vous pouvez utiliser le modèle de rappel. Dans cet exemple, une fonction (onColorSelected) est transmise à l'enfant. L'enfant appelle la fonction lorsqu'un bouton est enfoncé:

import 'package:flutter/material.Dart';

class Parent extends StatefulWidget {
  @override
  State<StatefulWidget> createState() {
    return ParentState();
  }
}

class ParentState extends State<Parent> {
  Color selectedColor = Colors.grey;

  @override
  Widget build(BuildContext context) {
    return Column(
      children: <Widget>[
        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: <Widget>[
        RaisedButton(
          child: Text('red'),
          color: Colors.red,
          onPressed: () {
            onColorSelect(Colors.red);
          },
        ),
        RaisedButton(
          child: Text('green'),
          color: Colors.green,
          onPressed: () {
            onColorSelect(Colors.green);
          },
        ),
        RaisedButton(
          child: Text('blue'),
          color: Colors.blue,
          onPressed: () {
            onColorSelect(Colors.blue);
          },
        )
      ],
    );
  }
}

typedef ColorCallback = void Function(Color color);

Les widgets Flutter internes tels que les boutons ou les champs de formulaire utilisent exactement le même modèle. Si vous souhaitez uniquement appeler une fonction sans argument, vous pouvez utiliser le type VoidCallback à la place pour définir votre propre type de rappel.


Si vous souhaitez notifier un parent supérieur, vous pouvez simplement répéter ce modèle à 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),
    )
  }
}

L'appel d'une méthode de widget enfant à partir d'un widget parent est déconseillé dans Flutter. Au lieu de cela, 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 autre approche est la classe controller dans Flutter (ScrollController, AnimationController, ...). Ils sont également transmis aux enfants en tant que paramètres de constructeur et contiennent des méthodes permettant de 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 ensuite écouter ces modifications pour mettre à jour leur état interne. Bien sûr, vous pouvez également implémenter votre propre classe de contrôleur. Si vous en avez besoin, je vous recommande de consulter le code source de Flutter pour comprendre son fonctionnement.


Les futurs et les flux sont une autre alternative à l’état de transmission, et pourraient également être utilisés pour appeler une fonction d’un enfant. 

Mais je ne le recommande vraiment pas. Si vous avez besoin d'appeler une méthode d'un widget enfant, c'est très probablement comme si votre architecture d'application était défectueuse. Essayez de déplacer l'état jusqu'à l'ancêtre commun!

13
boformer

si vous voulez appeler printSample () func, vous pouvez utiliser:

class Myapp extends StatefulWidget{
...
    MyappState myAppState=new MyappState();
    @override
    MyappState createState() => myAppState;
    void printSample(){
        myAppState.printSample();
    }
}
class MyAppState extends State<MyApp>{
    void printSample (){
        print("Sample text");
    }
}

...............
Myapp _myapp = new Myapp();
myapp.printSample();
...
0
Mehmet Akif BAYSAL

J'ai trouvé une autre solution par essais et erreurs, mais cela a fonctionné.

import 'main.Dart' as main;

Ajoutez ensuite cette ligne sous onPressed.

main.MyAppState().printSample();
0
mn128b