Im working on a company project. But I can't simply get the idea of how to implement a basic dropdown button into a function but I can't seem to make the values change in the dropdown function what do you think im doing wrong here's my code:
Widget buildDropdownField({
required String dropdownHeader,
required String dropdownValue
}){
return Column(
children: <Widget>[
Text(dropdownHeader),
const SizedBox(height: 10,),
//dropdownField
DropdownButton<String>(
value: dropdownValue,
icon: const Icon(Icons.arrow_downward),
elevation: 16,
style: const TextStyle(color: Colors.deepPurple),
underline: Container(
height: 2,
color: Colors.deepPurpleAccent,
),
onChanged: (String? newValue) {
setState(() {
dropdownValue = newValue!;
});
},
items: <String>['-', 'Geçti', 'Kaldı', 'Belirsiz']
.map<DropdownMenuItem<String>>((String value) {
return DropdownMenuItem<String>(
value: value,
child: Text(value),
);
}).toList(),
)
],
);
}
CodePudding user response:
Try below code hope its help to you. use StatefulBuilder Refer 
CodePudding user response:
First of all, you shouldn't update the parameter with the new value. It did update the parameter, but the function will still getting the value from it's calling.
I did not know the buildDropdownField function is inside a class or not, but it's okay and I will provide the solutions for both scenarios.
Within the Class
You need to create a variable within a class outside the functions.
class MyHomePage extends StatefulWidget {
const MyHomePage({Key? key, required this.title}) : super(key: key);
final String title;
@override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
String _dropDownValue = '-';
Widget buildDropdownField({required String dropdownHeader}) {
return Column(
children: <Widget>[
Text(dropdownHeader),
const SizedBox(
height: 10,
),
//dropdownField
DropdownButton<String>(
value: _dropDownValue,
icon: const Icon(Icons.arrow_downward),
elevation: 16,
style: const TextStyle(color: Colors.deepPurple),
underline: Container(
height: 2,
color: Colors.deepPurpleAccent,
),
onChanged: (String? newValue) {
setState(() {
_dropDownValue = newValue!;
});
},
items: <String>['-', 'Geçti', 'Kaldı',
'Belirsiz'].map<DropdownMenuItem<String>>((String value) {
return DropdownMenuItem<String>(
value: value,
child: Text(value),
);
}).toList(),
)
],
);
}
}
Outside the Class
You need to turn it into Stateful Widget in order for the drop down text to change. Once the dropdown is a stateful widget, you can use the solution above or a callback to make the changes on parent class.
class MyHomePage extends StatefulWidget {
const MyHomePage({Key? key, required this.title}) : super(key: key);
final String title;
@override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
String _dropDownValue = '-';
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: DropDownWidget(
dropdownHeader: 'Name',
dropdownValue: _dropDownValue,
onChanged: (String? newValue) {
setState(() {
_dropDownValue = newValue!;
});
},
),
),
);
}
}
class DropDownWidget extends StatefulWidget {
final String dropdownHeader;
final String dropdownValue;
final Function(String?)? onChanged;
DropDownWidget({required this.dropdownHeader, required this.dropdownValue, this.onChanged, Key? key}) : super(key: key);
@override
_DropDownWidgetState createState() => _DropDownWidgetState();
}
class _DropDownWidgetState extends State<DropDownWidget> {
@override
Widget build(BuildContext context) {
return Column(
children: <Widget>[
Text(widget.dropdownHeader),
const SizedBox(
height: 10,
),
//dropdownField
DropdownButton<String>(
value: widget.dropdownValue,
icon: const Icon(Icons.arrow_downward),
elevation: 16,
style: const TextStyle(color: Colors.deepPurple),
underline: Container(
height: 2,
color: Colors.deepPurpleAccent,
),
onChanged: widget.onChanged,
items: <String>['-', 'Geçti', 'Kaldı', 'Belirsiz'].map<DropdownMenuItem<String>>((String value) {
return DropdownMenuItem<String>(
value: value,
child: Text(value),
);
}).toList(),
)
],
);
}
}
CodePudding user response:
Wrap with StatefulBuilder it will work.
Widget buildDropdownField(
{required String dropdownHeader, required String dropdownValue}) {
return Column(
children: <Widget>[
Text(dropdownHeader),
const SizedBox(
height: 10,
),
StatefulBuilder(
builder: (_, setDropState) {
return DropdownButton<String>(
value: dropdownValue,
icon: const Icon(Icons.arrow_downward),
elevation: 16,
style: const TextStyle(color: Colors.deepPurple),
underline: Container(
height: 2,
color: Colors.deepPurpleAccent,
),
onChanged: (String? newValue) {
setDropState(() {
dropdownValue = newValue!;
});
},
items: <String>['-', 'Geçti', 'Kaldı', 'Belirsiz']
.map<DropdownMenuItem<String>>((String value) {
return DropdownMenuItem<String>(
value: value,
child: Text(value),
);
}).toList(),
);
},
)
],
);
}

