web-dev-qa-db-fra.com

Comment passer des données du widget enfant à son parent

J'ai le widget personnalisé ci-dessous qui crée un Switch et lit son statut (true/false)

Ensuite, j'ajoute celui-ci à mon widget d'application principal (parent). Comment puis-je faire en sorte que le parent connaisse la valeur du commutateur!

import 'package:flutter/material.Dart';

class Switchy extends StatefulWidget{
  Switchy({Key key}) : super(key: key);

  @override
  State<StatefulWidget> createState() => new _SwitchyState();
  }

class _SwitchyState extends State<Switchy> {
  var myvalue = true;

  void onchange(bool value) {
    setState(() {
      this.myvalue = value;      // I need the parent to receive this one!
      print('value is: $value');
    });
  }

  @override
  Widget build(BuildContext context) {
    return             
      new Card(
      child: new Container(
        child: new Row(
          mainAxisAlignment: MainAxisAlignment.end,
          children: <Widget>[
            new Text("Enable/Disable the app in the background",
              textAlign: TextAlign.left,
              textDirection: TextDirection.ltr,),
            new Switch(value: myvalue, onChanged: (bool value) => onchange(value)),
          ],
        ),
      ),
    );
  }
}

Dans le fichier main.Dart (parent), j'ai commencé avec ceci:

import 'widgets.Dart';
import 'package:flutter/material.Dart';

void main() => runApp(new MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      title: 'Flutter Demo',
      theme: new ThemeData(
        primarySwatch: Colors.deepOrange,
      ),
      home: new MyHomePage(title: 'My App settup'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);

  final String title;

  @override
  _MyHomePageState createState() => new _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {

  Widget e = new Switchy();
  //...

}
8
Hasan A Yousef

La première possibilité consiste à passer un rappel à votre enfant et la seconde à utiliser le modèle of pour votre widget avec état. Voir ci-dessous.

import 'package:flutter/material.Dart';

class MyStatefulWidget extends StatefulWidget {
  @override
  State<StatefulWidget> createState() => new MyStatefulWidgetState();

  static MyStatefulWidgetState of(BuildContext context) {
    final MyStatefulWidgetState navigator =
        context.ancestorStateOfType(const TypeMatcher<MyStatefulWidgetState>());

    assert(() {
      if (navigator == null) {
        throw new FlutterError(
            'MyStatefulWidgetState operation requested with a context that does '
            'not include a MyStatefulWidget.');
      }
      return true;
    }());

    return navigator;
  }
}

class MyStatefulWidgetState extends State<MyStatefulWidget> {
  String _string = "Not set yet";

  set string(String value) => setState(() => _string = value);

  @override
  Widget build(BuildContext context) {
    return new Column(
      children: <Widget>[
        new Text(_string),
        new MyChildClass(callback: (val) => setState(() => _string = val))
      ],
    );
  }
}

typedef void StringCallback(String val);

class MyChildClass extends StatelessWidget {
  final StringCallback callback;

  MyChildClass({this.callback});

  @override
  Widget build(BuildContext context) {
    return new Column(
      children: <Widget>[
        new FlatButton(
          onPressed: () {
            callback("String from method 1");
          },
          child: new Text("Method 1"),
        ),
        new FlatButton(
          onPressed: () {
            MyStatefulWidget.of(context).string = "String from method 2";
          },
          child: new Text("Method 2"),
        )
      ],
    );
  }
}

void main() => runApp(
      new MaterialApp(
        builder: (context, child) => new SafeArea(child: new Material(color: Colors.white, child: child)),
        home: new MyStatefulWidget(),
      ),
    );

Il existe également l'alternative d'utiliser un InheritedWidget au lieu d'un StatefulWidget; Cela est particulièrement utile si vous souhaitez que vos widgets enfants soient reconstruits si les données du widget parent changent et que le parent n'est pas un parent direct. Voir la documentation du widget inherited

12
rmtmckenzie

Vous pas.

En flottant, les données diminuent mais ne montent jamais. Si vous avez un jour besoin d’accéder à une donnée à l’intérieur d’un parent; déplacez ensuite les données vers ce parent et transmettez-les comme accessoires à l'enfant.

Dans votre cas, cela serait réalisé en supprimant la méthode onchange de _SwitchyState, puis en ajoutant un champ void onChange(bool value) à Switchy; que vous pouvez passer à Switch

0
Rémi Rousselet