Search code examples
fluttersetstateflutter-statedropdownbuttonflutter-dropdownbutton

SetState doesn't do its job - Flutter


When my DropdownButton updates the value it contains, it does so with it, the setState updates the highlight text of my button. But the same variable "ms" that is updated inside the button is not sent correctly to "EventiWidget", the first value of "ms" is always sent and even if inside the button ms it changes value inside "EventiWidget" " It's always the same.

String? ms;

class Eventi2 extends State<Eventi> {
  @override
  void initState() {
    super.initState();
    setState(() {});
    ms = meseAnnoAttuale;
    traduciMese();
  }

  @override
  Widget build(BuildContext context) {
    return Column(
      mainAxisSize: MainAxisSize.min,
      children: <Widget>[
        DropdownButton<String>(
          value: ms!,
          icon: const Icon(Icons.date_range),
          elevation: 16,
          style: TextStyle(color: Colors.blue[900], fontSize: 16),
          underline: Container(
            height: 2,
            color: Colors.blue[900],
          ),
          onChanged: (String? newValue) {
            ms = newValue;
            setState(() {});
          },
          items: <String>[
            'Agosto 2022',
            'Settembre 2022',
            'Ottobre 2022',
            'Novembre 2022',
            'Dicembre 2022',
            'Gennaio 2023',
            'Febbraio 2023',
            'Marzo 2023',
            'Aprile 2023',
            'Maggio 2023',
            'Giugno 2023',
            'Luglio 2023',
            'Agosto 2023'
          ].map<DropdownMenuItem<String>>((String value) {
            return DropdownMenuItem<String>(
              value: value,
              child: Text(value),
            );
          }).toList(),
        ),
        ElevatedButton.icon(
          onPressed: () {
            Navigator.push(
              context,
              MaterialPageRoute(builder: (context) => PaginaCreaEvento()),
            );
          },
          icon: Icon(Icons.add_circle, size: 18),
          label: Text("AGGIUNGI EVENTO"),
          style: ElevatedButton.styleFrom(
            shadowColor: Colors.blue,
            primary: Colors.blue[900],
          ),
        ),
        SizedBox(height: 5),
        EventiWidget(ms!),
      ],
    );
  }
}

this is a part of the EventWidget code

 // ignore: must_be_immutable
    class EventiWidget extends StatefulWidget {
      String meseAttualeEventi;
    
      EventiWidget(this.meseAttualeEventi);
    
      @override
      State<StatefulWidget> createState() {
        return EventiWidget2(meseAttualeEventi);
      }
    }
    
    class EventiWidget2 extends State<EventiWidget> {
  String meseAttualeEventi;

  EventiWidget2(this.meseAttualeEventi);
  List<Map<String, dynamic>> datiEventi = [];

  aggiornaWidgetEventi() async {
    if (meseAttualeEventi == "Agosto 2022") {
      datiEventi = datiEventiAgosto2022;
    } else if (meseAttualeEventi == "Settembre 2022") {
      datiEventi = datiEventiSettembre2022;
    } else if (meseAttualeEventi == "Ottobre 2022") {
      datiEventi = datiEventiOttobre2022;
    } else if (meseAttualeEventi == "Novembre 2022") {
      datiEventi = datiEventiNovembre2022;
    } else if (meseAttualeEventi == "Dicembre 2022") {
      datiEventi = datiEventiDicembre2022;
    } else if (meseAttualeEventi == "Gennaio 2023") {
      datiEventi = datiEventiGennaio2023;
    } else if (meseAttualeEventi == "Febbraio 2023") {
      datiEventi = datiEventiFebbraio2023;
    } else if (meseAttualeEventi == "Marzo 2023") {
      datiEventi = datiEventiMarzo2023;
    } else if (meseAttualeEventi == "Aprile 2023") {
      datiEventi = datiEventiAprile2023;
    } else if (meseAttualeEventi == "Maggio 2023") {
      datiEventi = datiEventiMaggio2023;
    } else if (meseAttualeEventi == "Giugno 2023") {
      datiEventi = datiEventiGiugno2023;
    } else if (meseAttualeEventi == "Luglio 2023") {
      datiEventi = datiEventiLuglio2023;
    } else if (meseAttualeEventi == "Agosto 2023") {
      datiEventi = datiEventiAgosto2023;
    }

    List<String> split = meseAttualeEventi.split(' ');
    String _mese = split[0];
    String _anno = split[1];
    await aggiornaEventi(_mese, _anno);
    await ordinaEventi(datiEventi);
    setState(() {});
  }

  @override
  void initState() {
    super.initState();
    aggiornaWidgetEventi();
  }

  @override
  Widget build(BuildContext context) {
    double larghezza = MediaQuery.of(context).size.width;
    return Expanded(
      child: ListView.builder(
          itemCount: datiEventi.length,
          shrinkWrap: true,
          padding: EdgeInsets.all(20),
          itemBuilder: (BuildContext context, int index) {
            String? A = datiEventi[index]['A'];
            String? B = datiEventi[index]['B'];
            String? C = datiEventi[index]['C'];
            String? D = datiEventi[index]['D'];
            String? E = datiEventi[index]['E'];
            String? data = datiEventi[index]['data'];
            return Card(
                elevation: 10.0,
                color: Colors.blue[700],
                child: Container(
                    padding: EdgeInsets.only(
                        top: 10,
                        bottom: 10,
                        left: larghezza / 8,
                        right: larghezza / 8),
                    child: Column(
                      mainAxisSize: MainAxisSize.min,
                      children: [
                        Text(
                          "$data",
                          style: TextStyle(
                              fontWeight: FontWeight.bold,
                              fontSize: 15,
                              color: Colors.black,
                              fontStyle: FontStyle.italic),
                        ),
                        SizedBox(height: 10),
                        Text(
                          "A: $A     B: $B\nC: $C     D: $D\nE: $E",
                          style: TextStyle(fontSize: 15, color: Colors.black),
                          textAlign: TextAlign.center,
                        ),
                      ],
                    )));
          }),
    );
  }
}

Solution

  • The problem is that EventiWidget2 is redeclaring meseAttualeEventi. Just remove it and reference it by widget.meseAttualeEventi. Also, override the didUpdateWidget method to check if the selected date has changed and call the async function again to refresh the data.

    To fix it do like the following:

    class EventiWidget extends StatefulWidget {
      String meseAttualeEventi;
    
      EventiWidget(this.meseAttualeEventi);
    
      @override
      State<StatefulWidget> createState() {
        return EventiWidget2();
      }
    }
    
    class EventiWidget2 extends State<EventiWidget> {
      List<Map<String, dynamic>> datiEventi = [];
    
      aggiornaWidgetEventi() async {
        if (widget.meseAttualeEventi == "Agosto 2022") {
          datiEventi = datiEventiAgosto2022;
        } else if (widget.meseAttualeEventi == "Settembre 2022") {
          datiEventi = datiEventiSettembre2022;
        } else if (widget.meseAttualeEventi == "Ottobre 2022") {
          datiEventi = datiEventiOttobre2022;
        } else if (widget.meseAttualeEventi == "Novembre 2022") {
          datiEventi = datiEventiNovembre2022;
        } else if (widget.meseAttualeEventi == "Dicembre 2022") {
          datiEventi = datiEventiDicembre2022;
        } else if (widget.meseAttualeEventi == "Gennaio 2023") {
          datiEventi = datiEventiGennaio2023;
        } else if (widget.meseAttualeEventi == "Febbraio 2023") {
          datiEventi = datiEventiFebbraio2023;
        } else if (widget.meseAttualeEventi == "Marzo 2023") {
          datiEventi = datiEventiMarzo2023;
        } else if (widget.meseAttualeEventi == "Aprile 2023") {
          datiEventi = datiEventiAprile2023;
        } else if (widget.meseAttualeEventi == "Maggio 2023") {
          datiEventi = datiEventiMaggio2023;
        } else if (widget.meseAttualeEventi == "Giugno 2023") {
          datiEventi = datiEventiGiugno2023;
        } else if (widget.meseAttualeEventi == "Luglio 2023") {
          datiEventi = datiEventiLuglio2023;
        } else if (widget.meseAttualeEventi == "Agosto 2023") {
          datiEventi = datiEventiAgosto2023;
        }
    
        List<String> split = widget.meseAttualeEventi.split(' ');
        String _mese = split[0];
        String _anno = split[1];
        await aggiornaEventi(_mese, _anno);
        await ordinaEventi(datiEventi);
        setState(() {});
      }
    
      @override
      void initState() {
        super.initState();
        aggiornaWidgetEventi();
      }
    
      @override
      void didUpdateWidget(covariant EventiWidget oldWidget) {
        super.didUpdateWidget(oldWidget);
        if (oldWidget.meseAttualeEventi != widget.meseAttualeEventi) {
          aggiornaWidgetEventi();
        }
      }
    
      @override
      Widget build(BuildContext context) {
        double larghezza = MediaQuery.of(context).size.width;
        return Expanded(
          child: ListView.builder(
              itemCount: datiEventi.length,
              shrinkWrap: true,
              padding: EdgeInsets.all(20),
              itemBuilder: (BuildContext context, int index) {
                String? A = datiEventi[index]['A'];
                String? B = datiEventi[index]['B'];
                String? C = datiEventi[index]['C'];
                String? D = datiEventi[index]['D'];
                String? E = datiEventi[index]['E'];
                String? data = datiEventi[index]['data'];
                return Card(
                    elevation: 10.0,
                    color: Colors.blue[700],
                    child: Container(
                        padding: EdgeInsets.only(
                            top: 10,
                            bottom: 10,
                            left: larghezza / 8,
                            right: larghezza / 8),
                        child: Column(
                          mainAxisSize: MainAxisSize.min,
                          children: [
                            Text(
                              "$data",
                              style: TextStyle(
                                  fontWeight: FontWeight.bold,
                                  fontSize: 15,
                                  color: Colors.black,
                                  fontStyle: FontStyle.italic),
                            ),
                            SizedBox(height: 10),
                            Text(
                              "A: $A     B: $B\nC: $C     D: $D\nE: $E",
                              style: TextStyle(fontSize: 15, color: Colors.black),
                              textAlign: TextAlign.center,
                            ),
                          ],
                        )));
              }),
        );
      }
    }