Saltar al contenido

¿Cómo establecer/actualizar el estado de StatefulWidget desde otro StatefulWidget en Flutter?

Esta duda se puede solucionar de diversas formas, sin embargo te enseñamos la que en nuestra opinión es la respuesta más completa.

Solución:

1. En el widget infantil: agregar parámetro Parámetro de función

class ChildWidget extends StatefulWidget 
  final Function() notifyParent;
  ChildWidget(Key key, @required this.notifyParent) : super(key: key);

2. En el widget principal: cree una función para que el niño devuelva la llamada

refresh() 
  setState(() );

3. En el widget principal: pase la función principal al widget secundario

new ChildWidget( notifyParent: refresh );  

4. En el widget infantil: llame a la función principal

  widget.notifyParent();

VIEJO: crea una instancia global de _MyHomePageState. Use esta instancia en _SubState como _myHomePageState.setState

NUEVO: No es necesario crear una instancia global. En su lugar, simplemente pase la instancia principal al widget secundario

CÓDIGO ACTUALIZADO SEGÚN FLUTTER 0.8.2:

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.blue,
      ),
      home: new MyHomePage(),
    );
  


EdgeInsets globalMargin =
    const EdgeInsets.symmetric(horizontal: 20.0, vertical: 20.0);
TextStyle textStyle = const TextStyle(
  fontSize: 100.0,
  color: Colors.black,
);

class MyHomePage extends StatefulWidget 
  @override
  _MyHomePageState createState() => _MyHomePageState();


class _MyHomePageState extends State 
  int number = 0;

  @override
  Widget build(BuildContext context) 
    return new Scaffold(
      appBar: new AppBar(
        title: new Text('SO Help'),
      ),
      body: new Column(
        children: [
          new Text(
            number.toString(),
            style: textStyle,
          ),
          new GridView.count(
            crossAxisCount: 2,
            shrinkWrap: true,
            scrollDirection: Axis.vertical,
            children: [
              new InkResponse(
                child: new Container(
                    margin: globalMargin,
                    color: Colors.green,
                    child: new Center(
                      child: new Text(
                        "+",
                        style: textStyle,
                      ),
                    )),
                onTap: () 
                  setState(() 
                    number = number + 1;
                  );
                ,
              ),
              new Sub(this),
            ],
          ),
        ],
      ),
      floatingActionButton: new FloatingActionButton(
        onPressed: () 
          setState(() );
        ,
        child: new Icon(Icons.update),
      ),
    );
  


class Sub extends StatelessWidget 

  _MyHomePageState parent;

  Sub(this.parent);

  @override
  Widget build(BuildContext context) 
    return new InkResponse(
      child: new Container(
          margin: globalMargin,
          color: Colors.red,
          child: new Center(
            child: new Text(
              "-",
              style: textStyle,
            ),
          )),
      onTap: () 
        this.parent.setState(() 
          this.parent.number --;
        );
      ,
    );
  

Solo déjame saber si funciona.

ingrese la descripción de la imagen aquí

Este ejemplo muestra llamar a un método

  1. Definido en el widget secundario del widget principal.
  2. Definido en el widget principal del widget secundario.

class ParentPage extends StatefulWidget 
  @override
  _ParentPageState createState() => _ParentPageState();


class _ParentPageState extends State 
  final GlobalKey _key = GlobalKey();

  @override
  Widget build(BuildContext context) 
    return Scaffold(
      appBar: AppBar(title: Text("Parent")),
      body: Center(
        child: Column(
          children: [
            Expanded(
              child: Container(
                color: Colors.grey,
                width: double.infinity,
                alignment: Alignment.center,
                child: RaisedButton(
                  child: Text("Call method in child"),
                  onPressed: () => _key.currentState.methodInChild(), // calls method in child
                ),
              ),
            ),
            Text("Above = ParentnBelow = Child"),
            Expanded(
              child: ChildPage(
                key: _key,
                function: methodInParent,
              ),
            ),
          ],
        ),
      ),
    );
  

  methodInParent() => Fluttertoast.showToast(msg: "Method called in parent", gravity: ToastGravity.CENTER);


class ChildPage extends StatefulWidget 
  final Function function;

  ChildPage(Key key, this.function) : super(key: key);

  @override
  ChildPageState createState() => ChildPageState();


class ChildPageState extends State 
  @override
  Widget build(BuildContext context) 
    return Container(
      color: Colors.teal,
      width: double.infinity,
      alignment: Alignment.center,
      child: RaisedButton(
        child: Text("Call method in parent"),
        onPressed: () => widget.function(), // calls method in parent
      ),
    );
  

  methodInChild() => Fluttertoast.showToast(msg: "Method called in child");

Puedes añadir valor a nuestro contenido informacional contribuyendo tu experiencia en las referencias.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *