
Hey Guys,
Have you ever been stuck and you dont know exact thing to do anymore, trust me, there are some bugs that won't just let you kill them (if you like use Bagon😂)...
Well I came across this bug 🐞 , yeah and I checked through Flutter documentation, Stack Overflow and the likes, couldn't get my solution.
I was able to figure it out after couple of hours and I will like to share my solution. Also I will be sharing some other solutions I came across just in case my solution doesnt fit. You can get all soluton in one stop, yah.
In this article you will be learning how to use DropDownButton and learn various properties of it in flutter and also get the solution to common bugs associated with this widget.
Lets dive in...
What is a Dropdown Button 💁🏽♂️?
Dropdown Button is a Material Design button for selecting from a list of items.
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? value) { // This is called when the user selects an item. setState(() { dropdownValue = value!; }); }, items: list.map<DropdownMenuItem<String>>((String value) { return DropdownMenuItem<String>( value: value, child: Text(value), ); }).toList(),
The Dropdown Button has some properties and methods, To use this widget, you need to have a list of items that you will use in your dropdown. For the above example here is the list that was used
const List list = ['One', 'Two', 'Three'];
and when you run this in your flutter project, you will get something like this: 👇🏼👇🏼👇🏼👇🏼👇🏼👇🏼
There you go!!!
Dropdown Button has a major?
You have to use this widget right, and if not, you get stuck. This is the major issue with using a Drondown Button.
Error meesage:
_Drop down Either or 2 more dropdown were detected with the same value???? _
Lets take this example as our point of focus.
String _value1; String _value2; final List<String> nameList = <String>[ "Name1", "Name2", "Name3", "Name4", "Name5", "Name6", "Name7", "Name8" ]; @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( elevation: 2.0, title: Text('Hello'), ), body: ListView( children: <Widget>[ Row( children: <Widget>[ Text('Name: '), Center( child: DropdownButton( value: _value1, onChanged: (value) { setState(() { _value1 = value; }); }, items: nameList.map( (item) { return DropdownMenuItem( value: item, child: new Text(item), ); }, ).toList(), ), ), ], ), Row( children: <Widget>[ Text('Name: '), Center( child: DropdownButton( value: _value2, onChanged: (value) { setState(() { _value2 = value; }); }, items: nameList.map( (item) { return DropdownMenuItem( value: item, child: new Text(item), ); }, ).toList(), ), ), ], ), ], ), backgroundColor: Colors.grey[200], ); } }
One:
Always make sure the value of the property "value" is not empty.
DropdownButton( // Initial Value _**value: dropdownvalue,**_ // Down Arrow Icon icon: const Icon(Icons.keyboard_arrow_down), // Array list of items items: items.map((String items) { return DropdownMenuItem( value: items, child: Text(items), ); }).toList(), // After selecting the desired option,it will // change button value to selected value onChanged: (String? newValue) { setState(() { dropdownvalue = newValue!; }); }, ),
Two:
If the value is going to be promised, that is at a later time the property will get its value, then. check if the value is empty first, if it is empty replaced with a default value.
DropdownButton( value: _value1.isNotEmpty ? _value1 : null, // guard it with null if empty items: nameList.map((item) { return DropdownMenuItem( value: item, child: new Text(item), ); }).toList(), );
Three:
If you are getting your list from the database, make sure the function you call in not in your build context, it should be called once. And the reson why that is so is because when call your api that will get the list within your build context, its get called multipble times as you are using setstate to update the selected value. Here is a complete example code ------
See here. 👇🏼👇🏼👇🏼👇🏼👇🏼👇🏼👇🏼
class _ParentBankState extends State<ParentCategory> { final _formKey = GlobalKey<FormState>(); String? _selectedBankCategory; // List category = []; final List<String> _parentCategory = [ "Select Category", ]; _//Make sure you do your calls here_ @override void initState() { //do your calls to get the list from your database //here so that it will be called once... final category = context.read<AddMoneyCubit>. ().loadBankList(); super.initState(); }@override Widget build(BuildContext context) { //Do not call your api here, why? //because buildcontext get build multiple times and that //will make your dropdwon throw that error, because it is //seeing the value beeing used repeatedly... var businessBankDropDown = BlocBuilder<AddMoneyCubit, AddMoneyState>( builder: (context, state) { return Form( key: _formKey, child: ButtonTheme( alignedDropdown: true, child: DropdownButtonHideUnderline( child: DropdownButton<String>( menuMaxHeight: 300, isExpanded: true, value: _selectedParentCategory, hint: const Text( "Parent Category", style: TextStyle(fontSize: 14), ), items: state is LoadBankList ? state.categoryListModel.map((e) { return DropdownMenuItem<String>( value: e.text, child: Row( children: [ Text( e.text, style: const TextStyle( fontSize: 14.0, color: IposColors.black), ), ], )); }).toList() : _parentBank.map((String value) { return DropdownMenuItem<String>( value: value, child: Row( children: [ Text( value, style: const TextStyle( fontSize: 14.0, color: IposColors.black), ), ], )); }).toList(), onChanged: (value) { setState(() { print(value); _selectedBankCategory = value; }); }, style: const TextStyle(fontSize: 30), ), ), ), ); }, ); return Container( width: MediaQuery.of(context).size.width, height: MediaQuery.of(context).size.height / 16.4, decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(10), border: Border.all( color: Colors.grey, ), ), child: businessBankDropDown); } }
This was my Solution.
Thank you for taking your time to go through this.
I hope you have learned to use this awesome widget and this helps you resolve your bugs 🐞🪲 issues...
If you would like to discuss this or any related issueChat Me. Follow me onTwitter for More...
Top comments(0)
For further actions, you may consider blocking this person and/orreporting abuse