Home > database >  Flutter DropdownButton doesn't allow me to select a different value from the drop down list
Flutter DropdownButton doesn't allow me to select a different value from the drop down list

Time:10-18

Here's my code

DropdownButton<int>(
                value: map['completedVersion'].toInt(), //selected
                elevation: 16,
                style: TextStyle(color: Theme.of(context).accentColor),
                underline: Container(
                  height: 2,
                  color: Colors.blueAccent,
                ),
                onChanged: (int? newValue) {
                  versionInput.text = newValue.toString();
                  },
                items: [for (var i = map['completedVersion'].toInt() as int; i <= map['requiredVersion']; i  ) i]
                    .map<DropdownMenuItem<int>>((int value) {
                  return DropdownMenuItem<int>(
                    value: value,
                    child: Text(value.toString()),
                  );
                }).toList(),
              )

Class level declaration

  TextEditingController versionInput = TextEditingController();

  @override
  void initState() {
    versionInput.text = map['completedVersion'].toString(); //set the initial value of text field
    super.initState();
  }

Here's the behavior

Dropdown

It doesn't let me select any other value (eg: 4,5,6). I do see that he onChanged() method is hit when I put in a break point. But I'm not sure why the selection goes back to the original value.

CodePudding user response:

TextEditingValue

class Example extends StatelessWidget {
  Example({Key? key}) : super(key: key);

  TextEditingController versionInput = TextEditingController(text: "2");

  @override
  Widget build(BuildContext context) {
    return Column(
      children: [
        ValueListenableBuilder(
          valueListenable: versionInput,
          builder: (BuildContext context, TextEditingValue selectedValue, Widget? child) {
            return DropdownButton<int>(
              value: int.parse(selectedValue.text),
              elevation: 16,
              style: TextStyle(color: Theme.of(context).accentColor),
              underline: Container(
                height: 2,
                color: Colors.blueAccent,
              ),
              onChanged: (value) {},
              items: [for (var i = 0 as int; i <= 6; i  ) i].map<DropdownMenuItem<int>>((int value) {
                return DropdownMenuItem<int>(
                  value: value,
                  child: Text(value.toString()),
                  onTap: () {
                    versionInput.text = value.toString();
                  },
                );
              }).toList(),
            );
          },
        ),
      ],
    );
  }
}

If you really use the TextEditingController without a text field and you don't need it, you can use it directly in the ValueNotifier.

ValueNotifier

class Example extends StatelessWidget {
  Example({Key? key}) : super(key: key);

  ValueNotifier<int> versionInput = ValueNotifier<int>(2); // initialValue

  @override
  Widget build(BuildContext context) {
    return Column(
      children: [
        ValueListenableBuilder(
          valueListenable: versionInput,
          builder: (BuildContext context, int selectedValue, Widget? child) {
            return DropdownButton<int>(
              value: selectedValue,
              elevation: 16,
              style: TextStyle(color: Theme.of(context).accentColor),
              underline: Container(
                height: 2,
                color: Colors.blueAccent,
              ),
              onChanged: (value) {},
              items: [for (var i = 0 as int; i <= 6; i  ) i].map<DropdownMenuItem<int>>((int value) {
                return DropdownMenuItem<int>(
                  value: value,
                  child: Text(value.toString()),
                  onTap: () {
                    versionInput.value = value;
                  },
                );
              }).toList(),
            );
          },
        ),
      ],
    );
  }
}

CodePudding user response:

You have to change two things :

1- value: map['completedVersion'].toInt(), ==> value: versionInput.text,

2-

onChanged: (newValue) {                     
    setState(() {
      versionInput.text = newValue.toString();
    });
},

CodePudding user response:

this should work:

  @override
  Widget build(BuildContext context) {
    return Column(
      children: [
        ValueListenableBuilder(
          valueListenable: versionInput,
          builder: (BuildContext context, TextEditingValue selectedValue, Widget? child) {
            return DropdownButton<int>(
            hint: Text(
            int.parse(selectedValue.text) ?? '3'
            ),
              elevation: 16,
              style: TextStyle(color: Theme.of(context).accentColor),
              underline: Container(
                height: 2,
                color: Colors.blueAccent,
              ),
              onChanged: (int? newValue) {
    if(newValue != null){
    setState(()=>   versionInput.text = newValue.toString());
    }
       },
              items: [for (var i = 0; i <= 6; i  ) i].map<DropdownMenuItem<int>>((int value) {
                return DropdownMenuItem<int>(
                  value: value,
                  child: Text(value.toString()),
                  onTap: () {
                    versionInput.text = value.toString();
                  },
                );
              }).toList(),
            );
          },
        ),
      ],
    );
  }
}

  • Related