Reputation: 57
I am developing a mobile application with Flutter. I am preparing a registration page for the application. On the registration page, I want to get the city and county where the user lives. I put two DropdownButtonForm
of this.
After the user selects the city in the first DropdownButtonForm
, the second DropdownButtonForm
will have county options. I was able to do this with this code:
List<DropdownMenuItem<String>> kahramanmarasDistricts = [
const DropdownMenuItem(
value: "Onikişubat",
child: Text("Onikişubat"),
),
const DropdownMenuItem(
value: "Dulkadiroğlu",
child: Text("Dulkadiroğlu"),
),
const DropdownMenuItem(
value: "Elbistan",
child: Text("Elbistan"),
),
const DropdownMenuItem(
value: "Afşin",
child: Text("Afşin"),
),
const DropdownMenuItem(
value: "Türkoğlu",
child: Text("Türkoğlu"),
),
const DropdownMenuItem(
value: "Pazarcık",
child: Text("Pazarcık"),
),
const DropdownMenuItem(
value: "Göksun",
child: Text("Göksun"),
),
const DropdownMenuItem(
value: "Andırın",
child: Text("Andırın"),
),
const DropdownMenuItem(
value: "Çağlayancerit",
child: Text("Çağlayancerit"),
),
const DropdownMenuItem(
value: "Nurhak",
child: Text("Nurhak"),
),
const DropdownMenuItem(
value: "Ekinözü",
child: Text("Ekinözü"),
),
];
List<DropdownMenuItem<String>> diyarbakirDistricts = [
const DropdownMenuItem(
value: "Bağlar",
child: Text("Bağlar"),
),
const DropdownMenuItem(
value: "Bismil",
child: Text("Bismil"),
),
const DropdownMenuItem(
value: "Çermik",
child: Text("Çermik"),
),
const DropdownMenuItem(
value: "Çınar",
child: Text("Çınar"),
),
const DropdownMenuItem(
value: "Çüngüş",
child: Text("Çüngüş"),
),
const DropdownMenuItem(
value: "Dicle",
child: Text("Dicle"),
),
const DropdownMenuItem(
value: "Egir",
child: Text("Eğir"),
),
const DropdownMenuItem(
value: "Ergani",
child: Text("Ergani"),
),
const DropdownMenuItem(
value: "Hani",
child: Text("Hani"),
),
const DropdownMenuItem(
value: "Hazro",
child: Text("Hazro"),
),
const DropdownMenuItem(
value: "Kayapınar",
child: Text("Kayapınar"),
),
const DropdownMenuItem(
value: "Hocaköy",
child: Text("Hocaköy"),
),
const DropdownMenuItem(
value: "Kulp",
child: Text("Kulp"),
),
const DropdownMenuItem(
value: "Lice",
child: Text("Lice"),
),
const DropdownMenuItem(
value: "Silvan",
child: Text("Silvan"),
),
const DropdownMenuItem(
value: "Sur",
child: Text("Sur"),
),
const DropdownMenuItem(
value: "Yenişehir",
child: Text("Yenişehir"),
),
];
List<DropdownMenuItem<String>> citys = [
const DropdownMenuItem(
value: "Kahramanmaraş",
child: Text("Kahramanmaraş"),
),
const DropdownMenuItem(
value: "Diyarbakır",
child: Text("Diyarbakır"),
),
];
// ...
SelectCityDropDownField(),
SelectDistrictDropDownField(),
Widget SelectCityDropDownField() {
return Theme(
data: Theme.of(context).copyWith(
colorScheme: ThemeData().colorScheme.copyWith(
primary: Colors.red,
),
),
child: DropdownButtonFormField(
decoration: InputDecoration(
prefixIcon: const Icon(
Icons.location_city,
color: Color(0xFFCB3126),
),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(50),
),
enabledBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(50),
borderSide: const BorderSide(
color: Color(0xFFCB3126),
),
),
),
items: citys
.map(
(e) => DropdownMenuItem<String>(
value: e.value,
child: e.child,
),
)
.toList(),
onChanged: (value) {
setState(() {
selectedCity = value.toString();
});
},
),
);
}
Widget SelectDistrictDropDownField() {
return Theme(
data: Theme.of(context).copyWith(
colorScheme: ThemeData().colorScheme.copyWith(
primary: Colors.red,
),
),
child: DropdownButtonFormField(
decoration: InputDecoration(
prefixIcon: const Icon(
Icons.location_city,
color: Color(0xFFCB3126),
),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(50),
),
enabledBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(50),
borderSide: const BorderSide(
color: Color(0xFFCB3126),
),
),
),
items: districtsItem(),
onChanged: (value) {
setState(() {
selectedDistrict = value.toString();
});
},
),
);
}
districtsItem() {
switch (selectedCity) {
case "Kahramanmaraş":
return kahramanmarasDistricts;
case "Diyarbakır":
return diyarbakirDistricts;
}
}
I'm having a problem with something. The problem is this: For example, let's choose the province of Kahramanmaraş
and choose Elbistan
as the district. Then when I change the city to Diyarbakır
, it gives an error. In other words, when I choose a different province after choosing the district, I get an error. This is error;
The following assertion was thrown building Builder(dirty, dependencies: [_FocusMarker]):
There should be exactly one item with [DropdownButtonFormField]'s value: Çermik.
Either zero or 2 or more [DropdownMenuItem]s were detected with the same value
'package:flutter/src/material/dropdown.dart':
Failed assertion: line 939 pos 15: 'items == null || items.isEmpty || value == null ||
items.where((DropdownMenuItem<T> item) {
return item.value == value;
}).length == 1'
How can I solve this problem? Thanks in advance for your help.
Upvotes: 2
Views: 44
Reputation: 702
It is because your districts' lists conflict when rendering.
You have to set key
property to distinguish them.
child: DropdownButtonFormField(
key: selectedCity == 'Kahramanmaraş'
? const Key('Kahramanmaraş')
: const Key('Diyarbakır'),
...
You could learn more about key
from below youtube link.
https://www.youtube.com/watch?v=kn0EOS-ZiIc&t=1s
Upvotes: 1