Drop down button in flutter not switching values to the selected value

Faced same issue and none of the answers worked. Then, I found the solution in one of my old projects.

I was using it in a AlertDialog here.

So, Change DropdownButton to DropdownButtonFormField

and add onSaved exactly as onChanged:

onSaved: (value) {
    setState(() {
        _selectedValue = value;
    });
}

That's it. It will start working.


I had this problem although I was already using the solution above.

for anyone who has this problem and the above solution does not work, try separating FutureBuilder from the dropdown. this is how your final code should look like:

class TheFuture extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return FutureBuilder(
      future: myFuture(),
      builder: (ctx, snp) {
        if (!snp.hasData) return LoadingLine();
        return TheBuilder(snp.data);
      },
    );
  }
}

class TheBuilder extends StatefulWidget {
  const TheBuilder(this.mp);
  final Map<String, dynamic> mp;
  @override
  _MessageUSScreenFilterBodyState createState() =>
      _MessageUSScreenFilterBodyState();
}

class _MessageUSScreenFilterBodyState extends State<MessageUSScreenFilterBody> {
  int _selectedId;

  @override
  Widget build(BuildContext context) {
    return DropdownButton<int>(
      selectedItemBuilder: (context) =>
          widget.mp['myData'].map((e) => Text(e.type)).toList(),
      items: widget.mp['myData']
          .map(
            (e) => DropdownMenuItem(
              child: Text(e.type),
              value: e.id,
            ),
          )
          .toList(),
      value: _selectedId,
      onChanged: (int _id) {
        setState(() {
          _selectedId = _id;
        });
      },
    );
  }
}

The error is because you are declaring a method variable newValue you must declare that variable as global inside your StatefulWidget.

   String newValue;

  Widget buildDropdownButton() {
  return new Padding(
    padding: const EdgeInsets.all(24.0),
    child: new Column(
      mainAxisAlignment: MainAxisAlignment.start,
      children: <Widget>[
        new ListTile(
          title: const Text('Frosting'),
          trailing: new DropdownButton<String>(
              hint: Text('Choose'),
              onChanged: (String changedValue) {
                newValue=changedValue;
                setState(() {
                  newValue;
                  print(newValue);
                });
              },
              value: newValue,
              items: <String>['None', 'Chocolate', 'Vanilla', 'ButterCream']
                  .map((String value) {
                return new DropdownMenuItem<String>(
                  value: value,
                  child: new Text(value),
                );
              }).toList()),
        ),
      ],
    ),
  );
  }

wrap dropdown button with StatefulBuilder and initialise newValue outside build method.

  StatefulBuilder(
          builder: (context, setState) => AlertDialog(
            title: Text("Change Status"),
            content: Container(
              padding: EdgeInsets.symmetric(horizontal: 8.0),
              decoration: BoxDecoration(
                  border: Border.all(color: Colors.grey, width: 1),
                  borderRadius: BorderRadius.circular(5)),
              child: DropdownButtonHideUnderline(
                child: DropdownButton(
                    hint: Text('Choose'),
                    onChanged: (String changedValue) {
                      setState(() {
                        newValue = changedValue;
                        print(newValue);
                      });
                    },
                    value: newValue,
                    items: <String>[
                      'None',
                      'Chocolate',
                      'Vanilla',
                      'ButterCream'
                    ].map((String value) {
                      return new DropdownMenuItem<String>(
                        value: value,
                        child: new Text(value),
                      );
                    }).toList()),
              ),
            ),
            
          ),
        ));