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;
}
)