Home > front end >  Drop Down value not updating to the selected option
Drop Down value not updating to the selected option

Time:10-26

I have gone through other similar questions but none of them work for me.

When I select the value in the Dropdown, setState method is called and the new value is stored in dropdownValue variable. But the change is not reflected on the screen.

class _ComparisonScreenState extends State<ComparisonScreen> {
  Widget titleWidget = const Text('Loading...'); //Initial widget which gets replaced by a drowpdown menu after async call to the DB returns values. 
  String dropdownValue = 'Contradiction 1'; //holds the initial value in the dropdown.

  @override
  void initState() {
    databaseObject.getContradictions().then( //async call to the DB to fetch data.
      (contradictions) { //stores the list of contradictions
        setState(
          () {
            titleWidget = DropdownButton<String>(
              isExpanded: true,
              // isDense: true,
              items: contradictions.header.map((String value) {
                return DropdownMenuItem<String>(
                  value: value,
                  child: ListTile(
                    title: Text(value),
                    subtitle: (Text(value)),
                  ),
                );
              }).toList(),
              value: dropdownValue,
              icon: const Icon(Icons.arrow_downward),
              iconSize: 24,
              style: const TextStyle(color: Colors.white),
              underline: Container(
                height: 2,
                color: Colors.white70,
              ),
              onChanged: (String? newValue) {
                setState(
                  () {
                    dropdownValue = newValue!;
                  },
                );
              },
            );
          },
        );
      },
    );
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      drawer: const CommonDrawer(currentScreen: 'ComparisonScreen'),
      appBar: AppBar(
        actions: const [
          Padding(
            padding: EdgeInsets.only(right: 20),
            child: Icon(Icons.settings),
          ),
        ],
        title: titleWidget,
      ),
      body: Container(),
    );
  }
}

thank you

CodePudding user response:

What i did, I use a method and pass the value

void changedData(String? value){
  dropdownValue = value!;
}

then in onChanged

onChanged: (String? newValue) {
                setState(
                  () {
                    changedData(newValue!)
                  },
                );
              },

I am not sure but you can try like this.

CodePudding user response:

I think its because your DropdownButton is in initState(). If I'm not wrong, SetState will rebuild build instead of initState() so, try to place your DropdownButton in build, and initialize your item for DropdownButton in initState().

CodePudding user response:

When you call setState() the framework schedules a new build call and widget sub-tree get recreated. Then the framework compares new widget sub-tree with the previous widget sub-tree to see if there is any changes. As your titleWidget object doesn't get recreated after selecting value from the dropdown, the dropdownValue doesn't get changed in the titleWidget. Simply this means you have to create new instances of widget objects to reflect their changes during the build call. There is a widget provided by the framework called FutureBuilder that you can use to build widgets asynchronously.

FutureBuilder(
    future: databaseObject.getContradictions,
    builder: (context, snapshot) {
        if (snapshot.hasData) {
            final contradictions = snapshot.data;
            return your_title_widget_here;
        }
        return your_loading_widget_here;
    }
)
  • Related