Flutter - There should be exactly one item with [DropdownButton]'s value - flutter

Please someone help me. I created DropdownButton with map key and values on StatefullWidget
I am using a map here because I am sending the selected key of value to the parent widget.
I am getting error:
There should be exactly one item with [DropdownButton]'s value: Все подряд.
Either zero or 2 or more [DropdownMenuItem]s were detected with the same value
As soon as I remove the value in the DropdownButton Widget, no error is thrown
title: Container(
child: DropdownButtonHideUnderline(
child: DropdownButton(
**value: _options[dropDownValue]**,
But in this case there is no value for the dropdown button
Full Code:
class _MyAppBarState extends State<MyAppBar> {
String dropDownValue = 'created';
Map<String, String> _options = {
'rating': 'Лучшие',
'seen': 'Интересные',
'created': 'Все подряд',
};
#override
Widget build(BuildContext context) {
return AppBar(
backgroundColor: Color(0xff62858F),
elevation: 20,
shadowColor: Colors.grey,
title: Container(
child: DropdownButtonHideUnderline(
child: DropdownButton(
value: _options[dropDownValue],
icon: const Icon(
Icons.arrow_drop_down,
color: Colors.white,
size: 25,
),
iconSize: 24,
elevation: 2,
selectedItemBuilder: (BuildContext context) {
return _options
.map((String key, String value) {
print(key);
print(value);
return MapEntry(
key,
Padding(
padding: EdgeInsets.symmetric(vertical: 15),
child: Text(
value,
style: TextStyle(
color: Colors.white,
fontWeight: FontWeight.bold,
fontSize: 17,
),
),
),
);
})
.values
.toList();
},
//underline:,
items: _options
.map(
(String key, String value) {
return MapEntry(
key,
DropdownMenuItem<String>(
value: key,
child: Text(
value,
style: TextStyle(
color: Colors.black,
),
),
),
);
},
)
.values
.toList(),
onChanged: (String newValue) {
widget.sortBy(newValue);
setState(() {
dropDownValue = newValue;
});
},
),
),
),
actions: <Widget>[
IconButton(
icon: Icon(
Icons.search,
size: 25,
),
onPressed: () {
Navigator.of(context).pushNamed(SearchPage.tag);
},
)
],
);
}
}

change your DropdownButton value property to just dropDownValue only (not _options[dropDownValue]).
Because in DropdownMenuItem you are setting value as the key of the MapEntry.

Related

Selected value from DropdownButton not showing in Flutter

I have a DropdownButton which displays user type.
List<String> items = ['Engineer', 'Technician', 'Sales'];
String? currentSelectedValue;
child: DropdownButtonHideUnderline(
child: Padding(
padding:
const EdgeInsets.symmetric(horizontal: 20.0),
child: DropdownButton<String>(
dropdownColor: Colors.blue.shade100,
isExpanded: true,
hint: Text('Select the user Type'),
onChanged: (newValue) {
setState(() {
currentSelectedValue = newValue;
});
print(currentSelectedValue);
},
items: items.map((String value) {
return DropdownMenuItem(
value: value,
child: Text(
value,
style: TextStyle(color: Colors.black),
),
);
}).toList(),
value: currentSelectedValue,
),
),
),
I can see the list, but when I select a value, it is not displaying on the Text portion of the DropdownButton. I could see the selected value printed in the console.
Can anyone help me to find the mistake?
Make sure to put currentSelectedValue outside the build method.
class Ft extends StatefulWidget {
const Ft({super.key});
#override
State<Ft> createState() => _FtState();
}
class _FtState extends State<Ft> {
List<String> items = ['Engineer', 'Technician', 'Sales'];
String? currentSelectedValue;
#override
Widget build(BuildContext context) {
return Scaffold(
body: DropdownButtonHideUnderline(
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 20.0),
child: DropdownButton<String>(
dropdownColor: Colors.blue.shade100,
isExpanded: true,
hint: Text('Select the user Type'),
onChanged: (newValue) {
setState(() {
currentSelectedValue = newValue;
});
print(currentSelectedValue);
},
items: items.map((String value) {
return DropdownMenuItem(
value: value,
child: Text(
value,
style: TextStyle(color: Colors.black),
),
);
}).toList(),
value: currentSelectedValue,
),
),
),
);
}
}

Dropdown menu in flutter

I have tried to build a dropdown button and a menu with it, where the value will be selected from the dropdown menu. The code is as below:
String valueChoose;
List listItem = ["A", "B", "C", "D", "E"];
DropdownButton(
hint: Text('Associate'),
dropdownColor: Colors.white,
icon: Icon(Icons.arrow_drop_down),
iconSize: 20.0,
style: TextStyle(
fontSize: 22.0,
color: Colors.black,
),
value: valueChoose,
onChanged: (newValue) {
setState(() {
valueChoose = newValue;
});
},
items: listItem.map((valueItem){
return DropdownMenuItem(
value: valueItem,
child: Text(valueItem),
);
}).toList(),
),
The error I'm facing is in the set state, where I've assigned newValue to the valueChoose.
A value of type 'Object?' can't be assigned to a variable of type 'String'.
Try changing the type of the variable, or casting the right-hand type to 'String'.
That is the error showing up for the newValue assinged in the set state. Please help regarding this, thanks in advance!
Below is the code, including the AlertDailog:
class HomeScreen extends StatefulWidget {
#override
_HomeScreenState createState() => _HomeScreenState();
}
class _HomeScreenState extends State<HomeScreen> {
String ? valueChoose;
List listItem = [
"A", "B", "C", "D", "E"
];
void assignPopup(BuildContext context) {
var alertDialog = AlertDialog(
content:
Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
Row(
children:[
Container(
child: Text(
'Action',
),
),
]
),
Row(
children:[
Container(
child: Card(
elevation: 5.0,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10.0),
),
child: TextField(
decoration: InputDecoration(
labelText: 'Please add any comments',
),
),
),
),
]
),
Row(
children:[
Container(
child: Text(
'Assign To',
),
),
]
),
Row(
children: [
Container(
child: Card(
elevation: 5.0,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10.0),
),
child: DropdownButton<String>(
hint: Text('Associate'),
dropdownColor: Colors.white,
icon: Icon(Icons.arrow_drop_down),
iconSize: 40.0,
style: TextStyle(
fontSize: 18.0,
color: Colors.black,
),
value: valueChoose,
onChanged: (newValue) {
setState(() {
valueChoose = newValue;
});
},
items: listItem.map<DropdownMenuItem<String>>((valueItem){
return DropdownMenuItem(
value: valueItem,
child: Text(valueItem),
);
}).toList(),
),
),
),
],
),
],
),
);
showDialog(
context: context,
builder: (BuildContext context) {
return alertDialog;
}
);
}
#override
Widget build(BuildContext context) {
return Scaffold(
...
...
Container(
child: TextButton(
onPressed: (){
assignPopup(context);
},
child: Text(
'Assign',
),
),
),
);
}
}
From the data that you provided I have created a example where I have used the alertdialog and inside it there is a drop down
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
// This widget is the root of your application.
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: HomeScreen(),
);
}
}
class HomeScreen extends StatefulWidget {
#override
_HomeScreenState createState() => _HomeScreenState();
}
class _HomeScreenState extends State<HomeScreen> {
String valueChoose;
List listItem = ["A", "B", "C", "D", "E"];
void assignPopup(BuildContext context) {
showDialog(
context: context,
builder: (BuildContext context) {
return StatefulBuilder(builder: (context, setState) {
return AlertDialog(
content: Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
Row(children: [
Container(
child: Text(
'Action',
),
),
]),
Row(children: [
Expanded(
child: Container(
child: Card(
elevation: 5.0,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10.0),
),
child: TextField(
decoration: InputDecoration(
labelText: 'Please add any comments',
),
),
),
),
),
]),
Row(children: [
Container(
child: Text(
'Assign To',
),
),
]),
Row(
children: [
Container(
child: Card(
elevation: 5.0,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10.0),
),
child: DropdownButton<String>(
hint: Text('Associate'),
dropdownColor: Colors.white,
icon: Icon(Icons.arrow_drop_down),
iconSize: 40.0,
style: TextStyle(
fontSize: 18.0,
color: Colors.black,
),
value: valueChoose,
onChanged: (newValue) {
setState(() {
valueChoose = newValue;
});
},
items: listItem
.map<DropdownMenuItem<String>>((valueItem) {
return DropdownMenuItem(
value: valueItem,
child: Text(valueItem),
);
}).toList(),
),
),
),
],
),
],
),
);
});
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Container(
child: TextButton(
onPressed: () {
assignPopup(context);
},
child: Text(
'Assign',
),
),
),
),
);
}
}
So here in order to change dropdown value you have to use the StatefulBuilder which will change your dropdown value. you can check the above example and make changes as per your needs.
Please run the code to check the desired output.
Let me know if it works.
Specify the types of DropdownButton and that map
String? valueChoose;
List listItem = ["A", "B", "C", "D", "E"];
DropdownButton<String>(
hint: Text('Associate'),
dropdownColor: Colors.white,
icon: Icon(Icons.arrow_drop_down),
iconSize: 20.0,
style: TextStyle(
fontSize: 22.0,
color: Colors.black,
),
value: valueChoose,
onChanged: (newValue) {
setState(() {
valueChoose = newValue;
});
},
items: listItem.map<DropdownMenuItem<String>>((valueItem) {
return DropdownMenuItem(
value: valueItem,
child: Text(valueItem),
);
}).toList(),
)
Declare variables outside the build method.
String? valueChoose;
List listItem = ["A", "B", "C", "D", "E"];
Inside the build method add the Dropdown widget, So the complete state class code would look like this,
class _DropdownViewState extends State<DropdownView> {
String? valueChoose;
List listItem = ["A", "B", "C", "D", "E"];
#override
Widget build(BuildContext context) {
return DropdownButton<String>(
hint: Text('Associate'),
dropdownColor: Colors.white,
icon: Icon(Icons.arrow_drop_down),
iconSize: 20.0,
style: TextStyle(
fontSize: 22.0,
color: Colors.black,
),
value: valueChoose,
onChanged: (String? newValue) {
setState(() {
valueChoose = newValue;
});
},
items: listItem.map<DropdownMenuItem<String>>((valueItem){
return DropdownMenuItem(
value: valueItem,
child: Text(valueItem),
);
}).toList(),
);
}

Dropdown is not keeping the value selected

I am working on a dropdown and I have the values in a variable, but I can't get the selected value to be shown, instead is always a static value on.
So far I did this:
class DropDownWidget extends State {
String dropdownValue = 'Activities';
String holder = '';
List<String> postType = ['Activities', 'Sell/buy', 'New Friends', 'City Recommendations', 'Post'];
void getDropDownItem() {
setState(() {
holder = dropdownValue;
});
}
#override
Widget build(BuildContext context) {
return Container(
height: 100,
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage('assets/img/blue.png'),
fit: BoxFit.cover,
),
),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
Container(
child: DropdownButton<String>(
value: dropdownValue,
icon: Icon(
Icons.keyboard_arrow_down_outlined,
color: TheBaseColors.lightRed,
),
iconSize: 30,
elevation: 16,
style: TextStyle(color: TheBaseColors.lightRed, fontSize: 18),
onChanged: (String data) {
setState(() {
dropdownValue = data;
});
switch (data) {
case 'Activities':
Navigator.push(
context,
MaterialPageRoute(builder: (context) => CreateActivity()),
);
break;
case 'Sell/buy':
Navigator.push(
context,
}
},
items: postType.map<DropdownMenuItem<String>>((String value) {
return DropdownMenuItem<String>(
value: value,
child: Text(value),
);
}).toList(),
),
),
],
),
);
}
}
I have saved the dropdow value in a variable and then set it in the SetState, but how to show the selected item each time?
Try This
String dropdownValue = 'Activities';
DropdownButton<String>(
value: dropdownValue,
icon: const Icon(Icons.arrow_downward),
iconSize: 24,
elevation: 16,
style: const TextStyle(color: Colors.deepPurple),
underline: Container(
height: 2,
color: Colors.deepPurpleAccent,
),
onChanged: (String? newValue) {
setState(() {
dropdownValue = newValue!;
});
},
items: <String>['Activities', 'Sell/buy', 'New Friends', 'City Recommendations', 'Post']
.map<DropdownMenuItem<String>>((String value) {
return DropdownMenuItem<String>(
value: value,
child: Text(value),
);
}).toList(),
),

How to have different color for dropdown label and dropdown list text in Flutter?

I am trying to use dropdown, and want to have Colors.white for the selected text, and Colors.black54 for the text of drop down list. But when I tried to use color attribute and change it to White, it also change the color of drop down text.
DropdownButton<String>(
//this changed the color of both text, intial text as well dropdown text color
dropdownColor: Colors.white,
value: value,
style: TextStyle(color: Colors.white),
icon: CircleAvatar(
radius: 12,
backgroundColor: Colors.white,
child: Icon(Icons.arrow_drop_down),
),
items: places.map((String value) {
return new DropdownMenuItem<String>(
value: value,
child: new Text(
value,
//I tried giving text style here , but same result
style: TextStyle(color: Colors.white),
),
);
}).toList(),
onChanged: (_) {
setState(() {
value = _;
});
},
)
Here is the picture of it.
Okay I found the Solution using selectedItemBuilder attribute of dropdown
final List<String> places = ['Delhi', 'Mumbai', 'Kerela', 'Agra'];
DropdownButton<String>(
selectedItemBuilder: (_) {
return places
.map((e) => Container(
alignment: Alignment.center,
child: Text(
e,
style: TextStyle(color: Colors.white),
),
))
.toList();
},
value: value,
icon: CircleAvatar(
radius: 12,
backgroundColor: Colors.white,
child: Icon(Icons.arrow_drop_down),
),
items: places.map((String value) {
return new DropdownMenuItem<String>(
value: value,
child: new Text(
value,
style: TextStyle(color: Colors.black54),
),
);
}).toList(),
onChanged: (_) {
setState(() {
value = _;
});
},
)
Here is the result

Flutter: custom made dropdown button function doesn't show selected value

I'm trying to make a custom function which returns a dropdown menu. The function takes 3 arguments: menuTitle, selectedValue and list of Strings.
List<String> cities= ['Rome', 'London', 'Paris'];
String selectedCity;
String title='Select a city';
Widget _buildDropdown(
String menuTitle, String selectedItem, List<String> list) {
return Container(
width: MediaQuery.of(context).size.width * 0.8,
margin: EdgeInsets.all(10.0),
decoration: BoxDecoration(
border: Border.all(color: Colors.grey[300]),
borderRadius: BorderRadius.circular(10.0)),
child: DropdownButtonHideUnderline(
child: ButtonTheme(
alignedDropdown: true,
child: DropdownButton<String>(
isExpanded: true,
hint: Text(
menuTitle.toUpperCase(),
style: GoogleFonts.lato(
textStyle: TextStyle(
color: Colors.grey[500],
fontWeight: FontWeight.bold,
)),
),
value: selectedItem,
items: list.map((String val) {
return DropdownMenuItem(
value: val,
child: Text(
val.toUpperCase(),
style: GoogleFonts.lato(
textStyle: TextStyle(
color: Colors.grey[500],
)),
),
);
}).toList(),
onChanged: (String value) {
setState(() {
selectedItem = value;
});
},
),
),
),
);
}
Dropdown menu shows all options available, but after choosing one, I can only see the hint text and not the selected value. I would appreciate any help.
For your dropdown to reflect on your selectedValue, it should be a part of the state. So follow as shown in the code below. I have tested this code and its working for me.
class _MyAppState extends State<MyApp> {
List<String> cities= ['Rome', 'London', 'Paris'];
//Initialize your selectedItem to selectedCity
//default selectedCity
String selectedCity='Rome';
String title='Select a city';
#override
Widget build(BuildContext context) {
Color color=Colors.blueAccent;
int x=color.value;
return MaterialApp(
home: Scaffold(
body: Column(
children: <Widget>[_buildDropdown("Title","",cities)],
),
),
);
}
Widget _buildDropdown(
String menuTitle, String selectedItem, List<String> list) {
return Container(
margin: EdgeInsets.all(10.0),
decoration: BoxDecoration(
border: Border.all(color: Colors.grey[300]),
borderRadius: BorderRadius.circular(10.0)),
child: DropdownButtonHideUnderline(
child: ButtonTheme(
alignedDropdown: true,
child: DropdownButton<String>(
isExpanded: true,
hint: Text(
menuTitle.toUpperCase(),
),
value: selectedCity,
items: list.map((String val) {
return DropdownMenuItem(
value: val,
child: Text(
val.toUpperCase(),
),
);
}).toList(),
onChanged: (String value) {
setState(() {
selectedCity = value;
});
},
),
),
),
);
}
}