I make Seprate DropDownButton custom StatelessWidget class but its give me error.
Error=>
There should be exactly one item with [DropdownButton]'s value: Instance of 'Company'. Either zero or 2 or more [DropdownMenuItem]s were detected with the same value 'package:flutter/src/material/dropdown.dart': Failed assertion: line 882 pos 15: 'items == null || items.isEmpty || value == null || items.where((DropdownMenuItem item) { return item.value == value; }).length == 1'
**
Code **
This is my custom class
import "package:flutter/material.dart";
class MyDropDown<T> extends StatelessWidget {
List<DropdownMenuItem<T>> items;
final T value;
String hintText;
ValueChanged<T?> onChanged;
MyDropDown(
{Key? key,
required this.items,
required this.value,
required this.hintText,
required this.onChanged})
: super(key: key);
@override
Widget build(BuildContext context) {
return Container(
padding: EdgeInsets.symmetric(horizontal: 10.0),
decoration: BoxDecoration(
color: Colors.white,
border: Border.all(
color: Colors.grey,
width: 0.3,
),
borderRadius: BorderRadius.all(
Radius.circular(
30.0,
),
),
),
child: Row(
children: [
Expanded(
// T
child: DropdownButton<T>(
hint: Text(
hintText,
style: TextStyle(),
),
isExpanded: true,
value: value,
items: items,
onChanged: onChanged,
underline: Container(),
),
)
],
),
);
}
}
=> This is my model class
class Company {
int? cId;
String? cName;
Company({ this.cId, this.cName});
}
=> Where i am use this class
import 'package:flutter/material.dart';
import 'package:sqllite_chart/widget/custom_dropdown_widget.dart';
import 'package:sqllite_chart/widget/custom_textformfield_widget.dart';
class MachineDataAddDialog extends StatefulWidget {
MachineDataAddDialog({Key? key}) : super(key: key);
@override
State<MachineDataAddDialog> createState() => _MachineDataAddDialogState();
}
class _MachineDataAddDialogState extends State<MachineDataAddDialog> {
TextEditingController textEditingControllerMId = TextEditingController();
TextEditingController textEditingControllerMName = TextEditingController();
TextEditingController textEditingControllerMTypeId = TextEditingController();
TextEditingController textEditingControllerMTypeName =
TextEditingController();
TextEditingController textEditingControllerCWGId = TextEditingController();
TextEditingController textEditingControllerCWGName = TextEditingController();
TextEditingController textEditingControllerMDesc = TextEditingController();
List<Company> companies = [
Company(cId: 1, cName: 'ABC'),
Company(cId: 2, cName: 'PQR'),
Company(cId: 3, cName: 'RST'),
Company(cId: 4, cName: 'GFI'),
Company(cId: 5, cName: 'XYZ')
];
List<DropdownMenuItem<Company>> companyListDropDownItems = [];
Company? selectedCompany;
int selectedCompanyId = 1;
String selectedCompanyTitle = 'ABC';
List<DropdownMenuItem<Company>> buildCompanyList(List company) {
List<DropdownMenuItem<Company>> items = [];
for (Company companyList in company) {
items.add(
DropdownMenuItem(
value: companyList,
child: Row(
children: [
Text(
'${companyList.cName}',
style: TextStyle(
color: Color.fromRGBO(49, 87, 110, 1.0),
),
),
],
),
),
);
}
return items;
}
void onChangeActivityListDropDownItem(Company? selected) {
setState(() {
selectedCompany = selected!;
selectedCompanyId = selected.cId!;
selectedCompanyTitle = selected.cName!;
});
}
@override
void initState() {
selectedCompany=Company();
companyListDropDownItems = buildCompanyList(companies);
super.initState();
}
@override
Widget build(BuildContext context) {
return AlertDialog(
title: const Align(
alignment: Alignment.bottomCenter,
child: Text("Enter Machine Details",
style: TextStyle(
shadows: [
Shadow(
color: Color.fromRGBO(49, 87, 110, 1.0),
offset: Offset(0, -5))
],
color: Colors.transparent,
decorationColor: Color.fromRGBO(49, 87, 110, 1.0),
decoration: TextDecoration.underline,
decorationThickness: 1,
decorationStyle: TextDecorationStyle.double,
)),
),
content: SingleChildScrollView(
child: Column(
children: [
CustomTextFormFieldWidget(
controller: textEditingControllerMId,
keyboardType: TextInputType.number,
hintText: "Enter Machine Id",
),
SizedBox(
height: 5
),
CustomTextFormFieldWidget(
controller: textEditingControllerMName,
keyboardType: TextInputType.text,
hintText: "Enter Machine Name",
),
SizedBox(
height: 5
),
CustomTextFormFieldWidget(
controller: textEditingControllerMTypeId,
keyboardType: TextInputType.number,
hintText: "Enter Machine Type ID",
),
SizedBox(
height: 5
),
CustomTextFormFieldWidget(
controller: textEditingControllerMTypeName,
keyboardType: TextInputType.text,
hintText: "Enter Machine Type Name",
),
SizedBox(
height: 5
),
MyDropDown<Company>(
hintText: 'Company',
value: selectedCompany!,
items: companyListDropDownItems,
onChanged:onChangeActivityListDropDownItem,
),
SizedBox(
height: 5
),
CustomTextFormFieldWidget(
controller: textEditingControllerCWGId,
keyboardType: TextInputType.number,
hintText: "Enter CWG Id",
),
SizedBox(
height: 5
),
CustomTextFormFieldWidget(
controller: textEditingControllerCWGName,
keyboardType: TextInputType.text,
hintText: "Enter CWG Name",
),
SizedBox(
height: 5
),
CustomTextFormFieldWidget(
controller: textEditingControllerMDesc,
keyboardType: TextInputType.text,
hintText: "Enter Machine Description",
maxLines: 2,
),
],
),
),
actions: [
Row(
children: [
Expanded(
flex: 4,
child: MaterialButton(
onPressed: () {
Navigator.of(context).pop();
},
color: Color.fromRGBO(49, 87, 110, 1.0),
child: Text("CANCEL", style: TextStyle(color: Colors.white)),
),
),
SizedBox(
width: 10,
),
Expanded(
flex: 4,
child: MaterialButton(
onPressed:() {},
child: Text("ADD", style: TextStyle(color: Colors.white)),
color: Color.fromRGBO(49, 87, 110, 1.0),
),
)
],
),
],
);
}
}
CodePudding user response:
Problem is while creating your companylist to pass to your custom widget, you pass companyList
as a value
, which you can not do because value expects String?
. You need to find a unique string that belongs to that company
DropdownMenuItem(
value: companyList,
child: Row(
children: [
Text(
'${companyList.cName}',
style: TextStyle(
color: Color.fromRGBO(49, 87, 110, 1.0),
),
),
],
),