es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Propiedad Child en Stateful Widget

He creado algunos widgets de prueba para ilustrar un punto con el que estoy teniendo dificultades en un widget mucho más complicado.

Tengo el siguiente widget:

class TestListWidget extends StatefulWidget {
  Widget child;

  TestListWidget({Widget child}) {
    this.child = child;
  }

  @override
  State<statefulwidget> createState() {
    return TestListWidgetState();
  }
}

class TestListWidgetState extends State<testlistwidget> {
  Widget child;

  int buttonCount = 0;

  @override
  initState() {
    child = widget.child;
  }

  _clickedCountButton() {
    setState(() {
      buttonCount++;
    });
  }

  @override
  Widget build(BuildContext context) {
    return new Column(children: [
      Text("Veces presionado: $buttonCount"),
      ElevatedButton(onPressed: _clickedCountButton, child: Text("Actualizar conteo")),
      child
    ]);
  }
}

El widget anterior se está utilizando dentro del siguiente widget:

class TestList extends StatefulWidget {
  @override
  State<statefulwidget> createState() {
    return new TestListState();
  }
}

class TestListState extends State<testlist> {
  String _testStr = "no presionado";

  _clickButton() {
    setState(() {
      _testStr = "PRESIONADO";
    });
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
        title: "Prueba",
        theme: ThemeData(
          primarySwatch: Colors.blue
        ),
        home: Scaffold(
          body: TestListWidget(child: Row(children: [
            Text(_testStr),
            ElevatedButton(onPressed: _clickButton, child: Text("¡Presióname!"))
          ]))
        )
      );
  }
}

El problema que tengo es que cuando se hace clic en el botón “¡Presióname!”, la función se llama, pero el texto en la pantalla no se actualiza a “PRESIONADO”. Sin embargo, el botón “Actualizar conteo” funciona como se esperaba.

Si convierto el TestListWidget en un widget sin estado (y elimino la funcionalidad del botón de actualización de conteo), entonces el botón “¡Presióname!” funciona como se espera. ¿Hay alguna manera de hacer que un widget secundario se reconstruya cuando se pasa a un widget con estado?

Tags:  , , , ,

Answer

  1. Avatar for davy.ai

    Sí, hay una forma de hacer que un widget secundario se reconstruya cuando se pasa a un widget con estado. Actualmente, en TestListWidget, el widget secundario solo se asigna una vez en el método initState() y no se actualiza cuando cambia el estado. Para reconstruir el widget secundario cuando cambia el estado, puedes agregar un método setState() en TestListWidgetState que actualice el widget secundario cada vez que el widget se actualice. Aquí tienes una versión actualizada de la clase TestListWidgetState:

    class TestListWidgetState extends State<testlistwidget> {
      int buttonCount = 0;
    
      void _clickedCountButton() {
        setState(() {
          buttonCount++;
        });
      }
    
      @override
      Widget build(BuildContext context) {
        return Column(
          children: [
            Text("Veces presionado: $buttonCount"),
            ElevatedButton(
              onPressed: _clickedCountButton, 
              child: Text("Actualizar contador")
            ),
            widget.child
          ],
        );
      }
    
      @override
      void didUpdateWidget(TestListWidget oldWidget) {
        super.didUpdateWidget(oldWidget);
        if (oldWidget.child != widget.child) {
          // Actualizar el widget secundario si ha cambiado
          setState(() {
            widget.child = widget.child;
          });
        }
      }
    }
    

    En esta versión actualizada, agregamos un nuevo método llamado didUpdateWidget(), que se llama cada vez que el widget se actualiza. En este método, verificamos si el widget secundario ha cambiado comparando el widget nuevo con el antiguo. Si ha cambiado, actualizamos el estado con el nuevo widget secundario utilizando setState(). De esta manera, el widget secundario se reconstruye cada vez que el widget se actualiza y cualquier cambio en el estado del widget padre se refleja en el widget secundario.

Comments are closed.