Custom Widget not Rendering - flutter

I have made a custom DropDown Picker the problem is when I switch it, the widget does not get rendered
There are 2 Dropdowns on the UI. In different cases, the child dropDown may or may not be visible.
The problem only occurs if I have both parent and child dropdowns and in the next case, the two dropdowns are both visible.
These are the below cases of how my Dynamic UI is render
case 1 ) DropDown1 and Drop DropDown2 on the UI (Drop Down 2 is parent widget)
when the user clicks on dropDown 2 items the Main UI gets rendered.
(Drop Down 2 items Minutes, Hours, Day, Week)
DropDown 1 item changes as per drop down 2 )
class CustomDropDown extends StatefulWidget {
final List<String> dropDownList;
final defaultVal;
final Function selectedItem;
final customDropDownId;
final isExpanded;
final dropDownType;
const CustomDropDown(
{Key? key,
required this.dropDownList,
required this.defaultVal,
required this.selectedItem,
this.customDropDownId,
this.isExpanded = false,
required this.dropDownType})
: super(key: key);
#override
_CustomDropDownState createState() => _CustomDropDownState();
}
class _CustomDropDownState extends State<CustomDropDown> {
var chosenValue;
#override
void initState() {
super.initState();
print("initState");
chosenValue = widget.defaultVal;
}
#override
void didChangeDependencies() {
super.didChangeDependencies();
print("didChangeDependencies");
}
#override
void dispose() {
super.dispose();
print("dispose");
}
#override
Widget build(BuildContext context) {
ThemeData themeData = Theme.of(context);
print("dropDownList ${widget.dropDownList} defaultVal ${widget.defaultVal} chosenValue ${chosenValue} ");
if (widget.dropDownType == DropDownType.DROPDOWN_WITH_ARROW) {
return Material(
elevation: 10,
color: foreground_color,
borderRadius: BorderRadius.circular(10.r),
child: Padding(
padding: EdgeInsets.symmetric(horizontal: 5.w),
child: DropdownButton<String>(
value: chosenValue,
isExpanded: widget.isExpanded,
dropdownColor: foreground_color,
icon: const Icon(Icons.keyboard_arrow_down_rounded),
borderRadius: BorderRadius.circular(10.r),
underline: const SizedBox(),
style: const TextStyle(color: Colors.white),
iconEnabledColor: Colors.white,
items: widget.dropDownList
.map<DropdownMenuItem<String>>((String value) {
return DropdownMenuItem<String>(
value: value,
child: Text(
value,
style: const TextStyle(color: Colors.white),
),
);
}).toList(),
onChanged: (String? value) {
if (value != null) {
setState(() {
chosenValue = value;
widget.selectedItem(chosenValue, widget.customDropDownId);
});
}
},
),
),
);
}
Parent Widget
Widget repeatEveryWidget(chosenValue) {
if (chosenValue == dropDownJobList[0] ||
chosenValue == dropDownJobList[1]) {
bool isMinutesWidget = chosenValue == dropDownJobList[0];
List<String> dropDownList = isMinutesWidget ? minutesList : hourList;
return CustomDropDown(
isExpanded: false,
dropDownList: dropDownList,
defaultVal:
isMinutesWidget ? defaultMinuteSelected : defaulHourSelected,
dropDownType: DropDownType.DROPDOWN_WITH_ARROW,
selectedItem: (String selectedVal, DropDownsType dropDownId) {
if (isMinutesWidget) {
defaultMinuteSelected = selectedVal;
} else {
defaulHourSelected = selectedVal;
}
},
customDropDownId: DropDownsType.CustomId,
);
} else {
return const SizedBox();
}
}
Parent Calling
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
const Text(REPEAT_EVERY),
SizedBox(
width: 10.w,
),
repeatEveryWidget(chosenValue),
SizedBox(
width: 10.w,
),
CustomDropDown(
dropDownList: dropDownCustomList,
defaultVal: chosenValue,
dropDownType: DropDownType.DROPDOWN_WITH_ARROW,
selectedItem:
(String selectedVal, DropDownsType dropDownId) {
setState(() {
chosenValue = selectedVal;
});
},
customDropDownId:
DropDownsTypeRepeatPicker,
),
],
),
)
Output
If the user selects item 1 Minute and then selects any item other than hours the child drop down gets removed from UI. But when the user selects hours after a minute the Items in Child widget renders but the defaultValue of this does not pick a new value it retains the old data that was picked in minutes as the UI has not been destroyed.

The answer to the above question lies in statement management in a flutter.
As there are two lists which has string object and some data are identical like "5","10"
const List<String> minutesListConfig = ['5', '10', '15', '30', '45', '60'];
const List<String> hourListConfig = ['1', '2', '3','4', '5', '6', '7','8', '9', '10', '11','12'];
As said by the flutter team every widget has an element that keeps track of its state whenever you try to render identical object type in dropdown list it will not render the new list.
If you want the widget tree to make sure to render the dropdown widget in 2 different ways then you will have to use KEY
In this case, the Object key can be used to make sure in background flutter makes 2 different dropdown lists for both the cases and does not render the dropdown as 1 widget.
return CustomDropDown(
key: ObjectKey(chosenValue),
isExpanded: false,
dropDownList: dropDownList,
defaultVal:
isMinutesWidget ? defaultMinuteSelected : defaulHourSelected,
dropDownType: DropDownType.DROPDOWN_WITH_ARROW,
selectedItem: (String selectedVal, DropDownsType dropDownId) {
if (isMinutesWidget) {
defaultMinuteSelected = selectedVal;
} else {
defaulHourSelected = selectedVal;
}
},
customDropDownId: DropDownsType.CustomId,
);
if (widget.dropDownType == DropDownType.DROPDOWN_WITH_ARROW) {
return Material(
elevation: 10,
color: foreground_color,
borderRadius: BorderRadius.circular(10.r),
child: Padding(
padding: EdgeInsets.symmetric(horizontal: 5.w),
child: DropdownButton<String>(
key:widget.key
value: chosenValue,
isExpanded: widget.isExpanded,
dropdownColor: foreground_color,
icon: const Icon(Icons.keyboard_arrow_down_rounded),
borderRadius: BorderRadius.circular(10.r),
underline: const SizedBox(),
style: const TextStyle(color: Colors.white),
iconEnabledColor: Colors.white,
items: widget.dropDownList
.map<DropdownMenuItem<String>>((String value) {
return DropdownMenuItem<String>(
value: value,
child: Text(
value,
style: const TextStyle(color: Colors.white),
),
);
}).toList(),
onChanged: (String? value) {
if (value != null) {
setState(() {
chosenValue = value;
widget.selectedItem(chosenValue, widget.customDropDownId);
});
}
},
),
),
);
Flutter team video on keys
https://www.youtube.com/watch?v=kn0EOS-ZiIc

Related

reset dropdown menu flutter

how to reset dropdonw to defult value after press button ?
i am trying to press button to reset dropdownmune to its defualt
class drawarScreen extends StatelessWidget {
const drawarScreen({super.key});
#override
Widget build(BuildContext context) {
List<String> list = <String>['One', 'Two', 'Three', 'Four'];
String? dropdownValue;
return Scaffold(
body: Column(children:[
DropdownButton<String>(
hint: Text('moammed'),
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(),
);
},
ElevatedButton(
onPress:(){
setstate({
dropdownValue='';
});
},child: Text("reste");
)
]);
}
}
i am trying to press button to reset dropdownmune to its defualt
resat dropdown menu in flutter
You need to put null value instead of empty string
setstate({
dropdownValue = null ;
});
If you like to have other than null, put it there.
And make sure to have StatefulWidget and variables outside the build method.
Full widget
class drawarScreen extends StatefulWidget {
const drawarScreen({super.key});
#override
State<drawarScreen> createState() => _drawarScreenState();
}
class _drawarScreenState extends State<drawarScreen> {
List<String> list = <String>['One', 'Two', 'Three', 'Four'];
String? dropdownValue;
#override
Widget build(BuildContext context) {
return Scaffold(
body: Column(
children: [
DropdownButton<String>(
hint: Text('moammed'),
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) {
setState(() {
dropdownValue = value;
});
},
items: list.map<DropdownMenuItem<String>>((String value) {
return DropdownMenuItem<String>(
value: value,
child: Text(value),
);
}).toList(),
),
ElevatedButton(
onPressed: () {
setState(() {
dropdownValue = null;
});
},
child: Text("Reset"))
],
),
);
}
}

Checkbox doesn't change when clicked in dropdownbutton

I am using DropdownButton and I am facing the following issue. I'm using a checkbox in elements, but when I click on an element, I don't get a checkmark indicating that the checkbox has been clicked. As a result, I need to close and reopen it, and then I will see the changes that were clicked on the "checkbox". The second problem is that when I select one element, all elements are selected for me. As a final result, I need to get so that I can select an element and the checkbox is immediately marked, if 2 elements are needed, then two, and so on. Tell me how to fix these problems, I will be grateful for the help?
dropdown
class DropdownWidget extends StatefulWidget {
List<String> items;
SvgPicture? icon;
double width;
DropdownWidget({
Key? key,
required this.items,
required this.icon,
required this.width,
}) : super(key: key);
#override
State<DropdownWidget> createState() => _DropdownWidgetState();
}
class _DropdownWidgetState extends State<DropdownWidget> {
String? selectedValue;
bool isChecked = false;
#override
void initState() {
super.initState();
if (widget.items.isNotEmpty) {
selectedValue = widget.items[1];
}
}
#override
Widget build(BuildContext context) {
return SizedBox(
width: widget.width,
child: DropdownButtonHideUnderline(
child: DropdownButton2(
items: widget.items
.map((item) => DropdownMenuItem<String>(
value: item,
child: Container(
decoration: BoxDecoration(
border: Border(
bottom: BorderSide(
color: constants.Colors.white.withOpacity(0.1),
width: 1,
),
),
),
child: Center(
child: Row(
children: [
if (item == selectedValue)
const SizedBox(
width: 0,
),
Expanded(
child: Text(
item,
style: constants.Styles.smallTextStyleWhite,
),
),
Checkbox(
checkColor: Colors.black,
value: isChecked,
onChanged: (bool? value) {
setState(() {
isChecked = value!;
});
},
),
],
),
),
),
))
.toList(),
value: selectedValue,
onChanged: (value) {
setState(() {
selectedValue = value as String;
});
},
icon: SvgPicture.asset(constants.Assets.arrowDropdown),
iconSize: 21,
buttonHeight: 27,
itemHeight: 47,
dropdownMaxHeight: 191,
dropdownWidth: 140,
dropdownDecoration: BoxDecoration(
borderRadius: BorderRadius.circular(8),
border: Border.all(
color: constants.Colors.purpleMain,
),
color: constants.Colors.greyDark,
),
selectedItemBuilder: (context) {
return widget.items.map(
(item) {
return Row(
children: [
widget.icon ?? const SizedBox(),
const SizedBox(width: 8),
Text(
item,
style: constants.Styles.bigBookTextStyleWhite,
),
],
);
},
).toList();
},
),
),
);
}
}
items
final List<String> items = const [
"All EV's",
'Main EV',
'<EV2>',
];
I hope this example explains the concept. For simplcity I made simple a new file, run it and see the results:
Then main idea in two lists, _checkList contain values of the CheckBox and _selectedList handles the main dropdown widget to show the selection.
Feel free to ask any questions and I'm happy to help
import 'package:flutter/material.dart';
class TestPage extends StatelessWidget {
const TestPage({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return const AnimationDemo(number: 5);
}
}
class AnimationDemo extends StatefulWidget {
const AnimationDemo({Key? key, this.number = 2}) : super(key: key);
final int number;
#override
State<AnimationDemo> createState() => _AnimationDemoState();
}
class _AnimationDemoState extends State<AnimationDemo> {
late List<bool> _checkList;
late List<int> _selectedIndex;
bool _isOpen = false;
#override
void initState() {
_checkList = List.filled(widget.number, false);
_selectedIndex = <int>[];
super.initState();
}
List<DropDownItem> generateItems() {
var tmp = <DropDownItem>[];
for (var i = 0; i < _checkList.length; i++) {
tmp.add(DropDownItem(
isChecked: _checkList[i],
onChanged: (value) {
setState(() {
_checkList[i] = value!;
if (value && !_selectedIndex.contains(i)) {
_selectedIndex.add(i);
} else {
_selectedIndex.remove(i);
}
});
},
));
}
return tmp;
}
#override
Widget build(BuildContext context) {
return SafeArea(
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: [
Row(
children: [
Expanded(
child: Text((_selectedIndex.isEmpty)
? 'Nothing Selected'
: _selectedIndex.join(',')),
),
GestureDetector(
onTap: () {
setState(() {
_isOpen = !_isOpen;
});
},
child: const Icon(Icons.arrow_downward),
),
],
),
AnimatedOpacity(
opacity: (_isOpen) ? 1 : 0,
duration: const Duration(milliseconds: 300),
child: Column(
mainAxisSize: MainAxisSize.min,
children: generateItems(),
),
)
],
),
);
}
}
class DropDownItem extends StatelessWidget {
final bool isChecked;
final Function(bool?)? onChanged;
const DropDownItem({Key? key, this.onChanged, this.isChecked = false})
: super(key: key);
#override
Widget build(BuildContext context) {
return Row(
children: [
const Expanded(child: Text('Demo item')),
Checkbox(value: isChecked, onChanged: onChanged)
],
);
}
}
Here's how to achieve the Multiselect dropdown with DropdownButton2:
final List<String> items = [
'Item1',
'Item2',
'Item3',
'Item4',
];
List<String> selectedItems = [];
#override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: DropdownButtonHideUnderline(
child: DropdownButton2(
isExpanded: true,
hint: Align(
alignment: AlignmentDirectional.center,
child: Text(
'Select Items',
style: TextStyle(
fontSize: 14,
color: Theme.of(context).hintColor,
),
),
),
items: items.map((item) {
return DropdownMenuItem<String>(
value: item,
//disable default onTap to avoid closing menu when selecting an item
enabled: false,
child: StatefulBuilder(
builder: (context, menuSetState) {
final _isSelected = selectedItems.contains(item);
return InkWell(
onTap: () {
_isSelected
? selectedItems.remove(item)
: selectedItems.add(item);
//This rebuilds the StatefulWidget to update the button's text
setState(() {});
//This rebuilds the dropdownMenu Widget to update the check mark
menuSetState(() {});
},
child: Container(
height: double.infinity,
padding: const EdgeInsets.symmetric(horizontal: 16.0),
child: Row(
children: [
_isSelected
? const Icon(Icons.check_box_outlined)
: const Icon(Icons.check_box_outline_blank),
const SizedBox(width: 16),
Text(
item,
style: const TextStyle(
fontSize: 14,
),
),
],
),
),
);
},
),
);
}).toList(),
//Use last selected item as the current value so if we've limited menu height, it scroll to last item.
value: selectedItems.isEmpty ? null : selectedItems.last,
onChanged: (value) {},
buttonHeight: 40,
buttonWidth: 140,
itemHeight: 40,
itemPadding: EdgeInsets.zero,
selectedItemBuilder: (context) {
return items.map(
(item) {
return Container(
alignment: AlignmentDirectional.center,
padding: const EdgeInsets.symmetric(horizontal: 16.0),
child: Text(
selectedItems.join(', '),
style: const TextStyle(
fontSize: 14,
overflow: TextOverflow.ellipsis,
),
maxLines: 1,
),
);
},
).toList();
},
),
),
),
);
}
Also, I've added it as an example to the package doc "Example 4" so you can get back to it later.

Selected item not showing in DropdownButton in Flutter

I need your help. I'm making a DropdownButton and I'm facing the following problem - I can't see the items that are selected in the DropdownMenuItems. I do not understand what the problem is that nothing is displayed. I'm using the [getwidget][1] package it's a GFCheckboxListTile widget - which just adds a checkbox. Please tell me how can I fix this error?
dropdown
import 'package:dropdown_button2/dropdown_button2.dart';
import 'package:flutter/material.dart';
import 'package:flutter_svg/svg.dart';
import 'package:getwidget/getwidget.dart';
import 'package:joyn/constants/constants.dart' as constants;
class DropdownWidget extends StatefulWidget {
List<String> items;
SvgPicture? icon;
double width;
DropdownWidget({
Key? key,
required this.items,
required this.icon,
required this.width,
}) : super(key: key);
#override
State<DropdownWidget> createState() => _DropdownWidgetState();
}
class _DropdownWidgetState extends State<DropdownWidget> {
String? selectedValue;
bool selected = false;
final List _selectedTitles = [];
final List _selectedTitlesIndex = [];
final GFCheckboxType type = GFCheckboxType.basic;
#override
void initState() {
super.initState();
if (widget.items.isNotEmpty) {
_selectedTitles.add(widget.items[1]);
}
}
void _onItemSelect(bool selected, int index) {
if (selected == true) {
setState(() {
_selectedTitles.add(widget.items[index]);
_selectedTitlesIndex.add(index);
});
} else {
setState(() {
_selectedTitles.remove(widget.items[index]);
_selectedTitlesIndex.remove(index);
});
}
}
#override
Widget build(BuildContext context) {
return SizedBox(
width: widget.width,
child: DropdownButtonHideUnderline(
child: DropdownButton(
items: List.generate(
widget.items.length,
(index) => DropdownMenuItem<String>(
value: widget.items[index],
child: Container(
decoration: BoxDecoration(
border: Border(
bottom: BorderSide(
color: constants.Colors.white.withOpacity(0.1),
width: 1,
),
),
),
child: GFCheckboxListTile(
value: _selectedTitles.contains(widget.items[index]),
onChanged: (bool selected) {
_onItemSelect(selected, index);
},
selected: selected,
title: Text(
widget.items[index],
style: constants.Styles.smallTextStyleWhite,
),
padding: const EdgeInsets.only(top: 14, bottom: 13),
margin: const EdgeInsets.only(right: 12, left: 2),
size: 22,
activeBgColor: constants.Colors.greyCheckbox,
activeBorderColor: Colors.red,
inactiveBgColor: constants.Colors.greyCheckbox,
activeIcon: SvgPicture.asset(constants.Assets.checkboxIcon),
inactiveBorderColor: constants.Colors.greyXMiddle,
type: type,
),
),
),
),
value: selectedValue,
onChanged: (value) {
setState(() {
selectedValue = value as String;
});
},
icon: SvgPicture.asset(constants.Assets.arrowDropdown),
iconSize: 21,
itemHeight: 66,
selectedItemBuilder: (context) {
return _selectedTitles.map(
(item) {
return Row(
children: [
widget.icon ?? const SizedBox(),
const SizedBox(width: 8),
Text(
item,
style: constants.Styles.bigBookTextStyleWhite,
),
],
);
},
).toList();
},
),
),
);
}
}
While the UI is need to update on DropdownMenuItem you can wrap GFCheckboxListTile with StatefulBuilder.
child: Container(
child: StatefulBuilder(
builder: (context, setStateSB) => GFCheckboxListTile(
value: _selectedTitles.contains(widget.items[index]),
onChanged: (bool selected) {
_onItemSelect(selected, index);
setStateSB(() {}); /// we are using StatefulBuilder's setState
///add your logic then
setState(() {
selectedValue = widget.items[index];
});
},
DropdownMenuItem ontap is outSide the GFCheckboxListTile therefore onChanged is not calling. I am using onChanged from GFCheckboxListTile to update the selectedValue.

Nesting ListView into DropdownMenu

I have created a custom ListView and I want to nest it into my Dropdownmenu as the item. Currently, I am getting the 'NoSuchMethodError : The method 'map' was called on null'. I can't seem to map it right. I am very new to Flutter.
The code for the ListView
class TheDetails extends StatelessWidget {
TheDetails({Key key}) : super(key: key);
#override
Widget build(BuildContext context) {
return ListView(
padding: const EdgeInsets.all(8.0),
itemExtent: 70.0,
children: <CustomListItem>[
CustomListItem(
accName: 'Salary Account',
accNumber: 'Savings XXX-X-XX563-9',
accBalance: '56,302.56',
),
CustomListItem(
accName: 'Salary Account 2',
accNumber: 'Savings XXX-X-XX563-9',
accBalance: '89,302.56',
),
CustomListItem(
accName: 'Vayu Meetang',
accNumber: 'Savings XXX-X-XX563-9',
accBalance: '100,505.56',
),
],
);
}
}
The code for the DropdownButton
class SelectAccount extends StatefulWidget {
#override
_SelectAccountState createState() => _SelectAccountState();
}
class _SelectAccountState extends State<SelectAccount> {
var dropdownValue;
var accountNames;
#override
Widget build(BuildContext context) {
return Container(
constraints: BoxConstraints.expand(width: 375.0, height: 120.0),
decoration: BoxDecoration(
color: Colors.white,
border: Border.all(color: Colors.grey),
borderRadius: BorderRadius.circular(20.0),
),
child: DropdownButton<String>(
value: dropdownValue,
underline: Container(
height: 2,
),
icon: Icon(Icons.keyboard_arrow_down,
color: Colors.blue[500],),
onChanged: (String newValue) {
setState(() {
dropdownValue = newValue;
});
},
items: accountNames.map((item){
return DropdownMenuItem(
value: item,
child: TheDetails(),
);
}).toList(),
),
);
}
}
You're calling .map() on accountNames which is not initialized, and therefore null at least on the first build. So doing var accountNames = []; will solve the issue.
A cleaner way to add a widget for each member of a list is :
items: [
for(var name in accountNames)
DropdownMenuItem(value: name, child: TheDetails()),
]
EDIT: Putting everything together :
// in top-level or another file
class Account {
Account(this.name, this.number, this.balance);
String name;
String number;
String balance;
}
// in _SelectAccountState or a provider
var selectedAccount = 'Savings XXX-X-XX563-9';
var accounts = [
Account(
'Salary Account',
'Savings XXX-X-XX563-7',
'56,302.56',
),
Account(
'Salary Account 2',
'Savings XXX-X-XX563-8',
'89,302.56',
),
Account(
'Vayu Meetang',
'Savings XXX-X-XX563-9',
'100,505.56',
),
];
// In the build method
DropdownButton<String>(
value: selectedAccount,
items: [
for(var account in accounts)
DropdownMenuItem<String>(
value: account.number,
child: Text(account.name),),
],
onChanged: (val) => setState(() => selectedAccount = val)
),

Flutter : how to pass value to Stateful widget?

I am new to flutter, I can easily create a stateless widget and require value to be set when creating an object (#required this.value)
However, I am a bit lost on how to do it with a stateful widget.
When looking at the code below, I want to be able to get "hint" value from the object created, into the stateful widget constructor, and down to the drop-down menu. I hope this makes sense.
class MyDropdownButton extends StatefulWidget { MyDropdownButton({
this.hint, }); String hint; #override _MyDropdownButtonState createState() => _MyDropdownButtonState(); }
class _MyDropdownButtonState extends State<MyDropdownButton> { String dropdownValue; String hint;
#override Widget build(BuildContext context) {
return Expanded(
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Text(
'TO',
style: TextStyle(color: kColourGreyText),
),
DropdownButton<String>(
value: dropdownValue != null ? dropdownValue : null,
hint: Text(hint),
icon: Icon(Icons.arrow_downward),
iconSize: 24,
elevation: 16,
style: TextStyle(color: kColourGreyText),
underline: Container(
height: 2,
color: kColorPrimary,
),
onChanged: (String newValue) {
setState(() {
dropdownValue = newValue;
});
},
items:
accountNameList.map<DropdownMenuItem<String>>((String value) {
return DropdownMenuItem<String>(
value: value,
child: Text(value),
);
}).toList(),
),
],
),
); } }
You can access widget properties from a state directly. Try widget.hint
Found multiple problems with your code,
class MyDropdownButton extends StatefulWidget {
MyDropdownButton({#required this.hint}); // use #required for required parameters, like this one here
final String hint; // use final
#override
_MyDropdownButtonState createState() => _MyDropdownButtonState();
}
// below line you missed `<MyDropdownButton>` after `State`,
// I'd suggest using a recommended IDE with a recommended Flutter
// Extention to generate code samples
class _MyDropdownButtonState extends State<MyDropdownButton> {
String dropdownValue;
// I added below 3 lines to avoid the errors in this sample code
List<String> accountNameList = [];
Color kColorPrimary = Colors.blue;
Color kColourGreyText = Colors.grey;
#override
Widget build(BuildContext context) {
// You don't need `Expanded` here, just wrap it with `Row` only
return Row(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text('TO', style: TextStyle(color: kColourGreyText)),
DropdownButton(
value: dropdownValue != null ? dropdownValue : null,
// when accessing parsed values in Statful,
// use widget.<variable name>
hint: Text(widget.hint),
icon: Icon(Icons.arrow_downward),
iconSize: 24,
elevation: 16,
style: TextStyle(color: kColourGreyText),
underline: Container(height: 2, color: kColorPrimary),
onChanged: (String newValue) {
setState(() {
dropdownValue = newValue;
});
},
items: accountNameList.map((String value) {
return DropdownMenuItem(value: value, child: Text(value));
}).toList(),
),
],
);
}
}
and again, I'd suggest using a recommended IDE with a recommended Flutter Extention to generate code samples