Home > Net >  widget into List<Widget> does not update into build method even if i call setState
widget into List<Widget> does not update into build method even if i call setState

Time:09-28

i have the following simple full code

import 'dart:developer';

import 'package:flutter/material.dart';

class Test extends StatefulWidget {
  const Test({Key? key}) : super(key: key);

  @override
  State<Test> createState() => _TestState();
}

class _TestState extends State<Test> {
  List myListWidget = [];
  late bool isColorWhie = false;
  @override
  Widget build(BuildContext context) {
    return GestureDetector(
      onTap: (){
        setState(() {
          myListWidget.add(
              Container(
                width: 50,
                height: 50,
                color: isColorWhie?Colors.white:Colors.red,
              )
          );
        });
      },
      child: Scaffold(
        backgroundColor: Colors.green,
        body: Center(
          child: Column(
            mainAxisSize: MainAxisSize.min,
            children: [
              ...myListWidget,
              TextButton(
                  onPressed: (){
                   setState(() {
                     isColorWhie = !isColorWhie; // here never update 
                     log('done');
                   });
                  },
                  child: const Text('tab to Change color',style: TextStyle(color: Colors.white),)
              )
            ],
          ),
        ),
      ),
    );
  }
}

i tap on any point on screen to add Container into myListWidget thn call setState(() {}); to update ui. everything fine now but when i change the isColorWhie to true it should change the color to white but it never update !

i am totally confused why it does not update ? And how could i handle with this ?

CodePudding user response:

Since you create a container as an object in GestureDetector and save it to your list, it will not change. It is now permanently saved (of course as long as you do not delete the element) as an entry in your list.

Your logic works exactly as you programmed it. For example, if you were to recompile the app and press the TextButton and then anywhere on your screen, a white container would also appear.

If you want to dynamically change the color of all containers at once, then you can do the following:

class _TestState extends State<Test> {
  int containerCounter = 0;
  late bool isColorWhie = false;
  @override
  Widget build(BuildContext context) {
    return GestureDetector(
      onTap: () {
        setState(() {
          containerCounter  ;
        });
      },
      child: Scaffold(
        backgroundColor: Colors.green,
        body: Center(
          child: Column(
            mainAxisSize: MainAxisSize.min,
            children: [
              Container(
                width: 50,
                child: ListView.builder(
                  shrinkWrap: true,
                  itemCount: containerCounter,
                  itemBuilder: ((context, index) {
                    return Container(
                      height: 50,
                      color: isColorWhie ? Colors.white : Colors.red,
                    );
                  }),
                ),
              ),
              TextButton(
                  onPressed: () {
                    setState(() {
                      isColorWhie = !isColorWhie; // here never update
                    });
                  },
                  child: const Text(
                    'tab to Change color',
                    style: TextStyle(color: Colors.white),
                  ))
            ],
          ),
        ),
      ),
    );
  }
}

CodePudding user response:

For base color change, I am using a separate button, also switching the list value. One thing variable does update the UI, you need to handle state inside the item(state-management property) or reinitialize the variable to get update state.

class Test extends StatefulWidget {
  const Test({Key? key}) : super(key: key);

  @override
  State<Test> createState() => _TestState();
}

class _TestState extends State<Test> {
  List<bool> myListWidgetState = [];
  bool isColorWhie = false;
  @override
  Widget build(BuildContext context) {
    return GestureDetector(
      onTap: () {
        setState(
          () {
            myListWidgetState.add(isColorWhie);
          },
        );
      },
      child: Scaffold(
        backgroundColor: Colors.green,
        body: Center(
          child: Column(
            mainAxisSize: MainAxisSize.min,
            children: [
              ...myListWidgetState.map(
                (e) {
                  return Container(
                    width: 50,
                    height: 50,
                    color: e ? Colors.white : Colors.red,
                  );
                },
              ),
              TextButton(
                onPressed: () {
                  myListWidgetState = myListWidgetState.map((e) => !e).toList();
                  setState(() {});

                  print(isColorWhie);
                },
                child: const Text(
                  'tab to Change color',
                  style: TextStyle(color: Colors.white),
                ),
              ),
              TextButton(
                onPressed: () {
                  setState(() {
                    isColorWhie = !isColorWhie;
                  });

                  print(isColorWhie);
                },
                child: const Text(
                  'tab to Change base color',
                  style: TextStyle(color: Colors.white),
                ),
              ),
            ],
          ),
        ),
      ),
    );
  }
}
  • Related