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.

Cómo actualizar el árbol de widgets desde otra clase de widget – Flutter

Estoy enfrentando un problema para volver a renderizar la página cuando una variable cambia en una clase/widget (ambos widgets son clases stateful).

Aquí está cómo va:
Tengo tres botones en una clase que cambian el estado de una variable (foodCategory).

int foodCategory = 0;
// más abajo en el cuerpo del botón elevado - estoy actualizando la variable
setState(() {
  foodCategory = 1;
});

Mientras tanto, en el otro widget, estoy usando esta variable para realizar ciertas acciones:

for (var item in foodItems.values.elementAt(foodCategory)) {
  GestureDetector(........ y así sucesivamente...
}

Sin embargo, en el segundo fragmento, el widget no sabe si ha habido un cambio y no está llamando al context de construcción de nuevo…
No estoy seguro de cómo superar este problema. He intentado usar valuelistenablebuilder pero en vano. Tal vez no sé cómo usarlo en el bucle (estoy usando foodCategory como un int (iterador)).

Tags:  , , ,

Answer

  1. Avatar for davy.ai

    Solución para volver a renderizar la página cuando una variable cambia en una clase/widget

    Para superar el problema de volver a renderizar la página cuando una variable cambia en una clase/widget, puedes usar la función setState() para reconstruir el árbol de widgets con los valores actualizados. En tu caso, ya estás utilizando setState() para actualizar el valor de foodCategory, pero el árbol de widgets no se reconstruye.

    Para hacer que el árbol de widgets se reconstruya, puedes mover la declaración de foodCategory a un widget padre y pasarlo al hijo como parámetro. Luego, puedes usar un ValueNotifier o ChangeNotifier para escuchar los cambios en el valor de foodCategory y reconstruir el árbol de widgets cuando cambie.

    Aquí tienes un ejemplo de implementación:

    Widget padre:

    class ParentWidget extends StatefulWidget {
      @override
      _ParentWidgetState createState() => _ParentWidgetState();
    }
    
    class _ParentWidgetState extends State<parentwidget> {
      ValueNotifier<int> foodCategory = ValueNotifier<int>(0);
    
      void _updateFoodCategory(int value) {
        setState(() {
          foodCategory.value = value;
        });
      }
    
      @override
      Widget build(BuildContext context) {
        return Column(
          children: [
            ChildWidget1(foodCategory: foodCategory),
            ChildWidget2(foodCategory: foodCategory),
            ElevatedButton(
              onPressed: () {
                _updateFoodCategory(1);
              },
              child: Text('Cambiar categoría de comida'),
            ),
          ],
        );
      }
    }
    

    Widget hijo 1:

    class ChildWidget1 extends StatelessWidget {
      final ValueNotifier<int> foodCategory;
    
      ChildWidget1({required this.foodCategory});
    
      @override
      Widget build(BuildContext context) {
        return ValueListenableBuilder<int>(
          valueListenable: foodCategory,
          builder: (BuildContext context, int value, Widget? child) {
            return Text('Categoría de comida actual: $value');
          },
        );
      }
    }
    

    Widget hijo 2:

    class ChildWidget2 extends StatefulWidget {
      final ValueNotifier<int> foodCategory;
    
      ChildWidget2({required this.foodCategory});
    
      @override
      _ChildWidget2State createState() => _ChildWidget2State();
    }
    
    class _ChildWidget2State extends State<childwidget2> {
      @override
      void initState() {
        super.initState();
        widget.foodCategory.addListener(_handleChange);
      }
    
      @override
      void dispose() {
        widget.foodCategory.removeListener(_handleChange);
        super.dispose();
      }
    
      void _handleChange() {
        setState(() {
          // Manejar los cambios en foodCategory aquí
        });
      }
    
      @override
      Widget build(BuildContext context) {
        return ValueListenableBuilder<int>(
          valueListenable: widget.foodCategory,
          builder: (BuildContext context, int value, Widget? child) {
            return ListView.builder(
              itemCount: value,
              itemBuilder: (BuildContext context, int index) {
                return GestureDetector(
                  // Realizar acciones aquí
                );
              },
            );
          },
        );
      }
    }
    

    En el ejemplo anterior, ParentWidget mantiene el estado de foodCategory y lo pasa a sus hijos como un ValueNotifier. ChildWidget1 escucha los cambios en foodCategory usando ValueListenableBuilder, y ChildWidget2 escucha los cambios usando addListener y removeListener.

    Cada vez que foodCategory cambia, se llama a la función setState() para reconstruir el árbol de widgets con el valor actualizado, de modo que los cambios se reflejan en la interfaz de usuario.

Comments are closed.