I use two dropdown menu here.
Both data come from API. And second's one data depends on first dropdown items. Thats mean when I select an item from first menu then data will come on second dropdown's. And It's changing dynamically.
I face a problem here. When I change a items from first dropdown, second dropdown show me a error.
Like this -
Before
After Change City value
Here is my Code for two dropdown
// Choose City
CustomDropDownMenu(
items: allCity.map((list) {
return DropdownMenuItem(
child: Padding(
padding: const EdgeInsets.only(left: 20.0),
child: Text(
"${list["name"]}",
style: TextStyle(),
),
),
onTap: () {
setState(() {
isVisible = false;
});
getWeight(list["id"]).then((value) => {
setState(() {}),
});
print(list["id"]);
FocusScope.of(context).unfocus();
print(weightList.length);
},
value: list["id"].toString(),
);
}).toList(),
value: _city,
hint: "Choose City",
onChanged: (value) {
setState(() {
this._city = value;
});
},
),
// Weight
CustomDropDownMenu(
hint: "Select Weight",
value: _weight,
items: [
DropdownMenuItem(child: Text("Select Weight")),
...weightList.map((list) {
return DropdownMenuItem(
child: Padding(
padding: const EdgeInsets.only(left: 20.0),
child: Text(
"${list["weight"]}",
style: TextStyle(),
),
),
onTap: () {
FocusScope.of(context).unfocus();
},
value: list["id"].toString(),
);
}).toList()
],
onChanged: (value) {
setState(() {
_weight = value;
});
},
),
Here is CustomDropDown() class
.. class CustomDropDownMenu extends StatelessWidget { final String hint; final dynamic value;
final Function onChanged; final Function onSaved; final List<DropdownMenuItem<dynamic>> items;
const CustomDropDownMenu({
Key key,
this.hint,
this.onChanged,
this.onSaved,
this.items,
this.value, }) : super(key: key); #override Widget build(BuildContext context) {
double _width = MediaQuery.of(context).size.width;
return Container(
decoration: BoxDecoration(
shape: BoxShape.rectangle,
borderRadius: BorderRadius.all(
Radius.circular(60),
),
),
child: Card(
shape: StadiumBorder(),
elevation: 5,
child: DropdownButtonFormField(
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 18.0,
color: Colors.black),
hint: Padding(
padding: const EdgeInsets.only(left: 20.0),
child: Text(
hint,
textAlign: TextAlign.end,
),
),
decoration: InputDecoration(
enabledBorder: UnderlineInputBorder(
borderSide: BorderSide(color: Colors.transparent),
),
),
value: value,
onChanged: onChanged,
onSaved: onSaved,
items: items,
),
)); } }
That's why I want to unselect second's on dropdown menu items programmatically, but not find a solution. Please some one help me.
set _weight value null on city change
Convert your CustomDropDownMenu into StatefulWidget and implement below code:
#override
void didUpdateWidget(covariant AppDropDown oldWidget) {
super.didUpdateWidget(oldWidget);
if (!listEquals(oldWidget.items, widget.items)) {
value = null;
}}
Related
I amm using two languages in my flutter, English and Arabic, when user select his city(cities will show in DropdownMenu) while registering in English language it works fine, he can update his profile by changing his city but when same user change language from English to Arabic and go to his profile section I get error.
How can I resolve this issue?
There should be exactly one item with [DropdownButton]'s value: Dubai. Either zero or 2 or more [DropdownMenuItem]s were detected with the same value 'package:flutter/src/material/dropdown.dart': Failed assertion: line 1580 pos 15: 'items == null || items.isEmpty || value == null || items.where((DropdownMenuItem<T> item) { return item.value == value; }).length == 1'
This error popup when English user change to Arabic language, and same when Arabic user change to English language.
Here is my Profile update code:
class Profile extends StatefulWidget {
final Function(Map<String, dynamic>) callBack;
const Profile(this.callBack, {Key? key}) : super(key: key);
#override
State<Profile> createState() => _ProfileState();
}
class _ProfileState extends State<Profile> {
List<String> cities = [
LanguageStringKeys.instance.abuDhabi.tr,
LanguageStringKeys.instance.dubai.tr,
LanguageStringKeys.instance.sharjah.tr,
LanguageStringKeys.instance.ajman.tr,
LanguageStringKeys.instance.ummAlQuwain.tr,
LanguageStringKeys.instance.rasAlKhaimah.tr,
LanguageStringKeys.instance.fujairah.tr,
];
String selectedCity = Get.put(AppController()).loginResponse?.data?.user?.address;
var nameController = TextEditingController();
var tradeController = TextEditingController();
var phoneController = TextEditingController();
var bioController = TextEditingController();
#override
void initState() {
super.initState();
WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
nameController.text = Get.put(AppController()).loginResponse?.data?.user?.firstName ?? "";
tradeController.text = Get.put(AppController()).loginResponse?.data?.user?.tradeLicense ?? "";
phoneController.text = Get.put(AppController()).loginResponse?.data?.user?.phone ?? "";
selectedCity = Get.put(AppController()).loginResponse?.data?.user?.address ?? "";
bioController.text = Get.put(AppController()).loginResponse?.data?.user?.bio ?? "";
});
}
#override
Widget build(BuildContext context) {
return BackgroundImage(
image: const AssetImage('assets/images/enjyback.png'),
child: GestureDetector(
onTap: () => FocusScope.of(context).unfocus(),
child: Scaffold(
backgroundColor: Colors.transparent,
body: Center(
child: SingleChildScrollView(
physics: const BouncingScrollPhysics(),
child: Padding(
padding: EdgeInsets.symmetric(horizontal: Dimensions.width20, vertical: Dimensions.height10),
child: Column(
children: [
AppTextField(
textController: nameController,
labelText: LanguageStringKeys.instance.name.tr,
labelColor: Colors.white,
borderColor: Colors.white,
textColor: Colors.white,
inputType: TextInputType.name,
),
SizedBox(height: Dimensions.height15),
AppTextField(
textController: tradeController,
labelText: LanguageStringKeys.instance.tradeLicenseNo.tr,
labelColor: Colors.white,
borderColor: Colors.white,
textInputFormatter: 7,
textColor: Colors.white,
inputType: TextInputType.number,
),
SizedBox(height: Dimensions.height15),
AppTextField(
textController: phoneController,
labelText: LanguageStringKeys.instance.phoneNumber.tr,
labelColor: Colors.white,
borderColor: Colors.white,
textColor: Colors.white,
inputType: TextInputType.number,
),
SizedBox(height: Dimensions.height15),
ButtonTheme(
alignedDropdown: true,
child: DropdownButtonFormField(
isExpanded: true,
borderRadius: BorderRadius.circular(Dimensions.height10),
iconEnabledColor: Colors.white,
selectedItemBuilder: (BuildContext context) {
return cities
.map((e) => Text(
selectedCity,
style: const TextStyle(color: Colors.white),
))
.toList();
},
decoration: textFormFieldsDecoration(
LanguageStringKeys.instance.city.tr,
Colors.white,
Colors.white,
),
items: cities
.map((item) => DropdownMenuItem(
value: item,
child: SmallText(text: item, color: Colors.black),
))
.toList(),
value: selectedCity,
onChanged: (item) => setState(() => selectedCity = item as String)),
),
SizedBox(height: Dimensions.height15),
AppTextField(
textController: bioController,
labelText: LanguageStringKeys.instance.bio.tr,
labelColor: Colors.white,
textColor: Colors.white,
maxLines: 6,
borderColor: Colors.white,
inputType: TextInputType.name,
),
SizedBox(height: Dimensions.height15),
ElevatedButton(
onPressed: () {
Provider.of<UserProfileService>(context, listen: false).updateUserProfile(context, {}, {
"name": nameController.text,
"trade_license": tradeController.text,
"phone": phoneController.text,
"address": selectedCity,
"bio": bioController.text,
"image": image,
});
},
style: ElevatedButton.styleFrom(
backgroundColor: Colors.white,
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(Dimensions.radius10)),
minimumSize: Size.fromHeight(Dimensions.height40),
),
child: SmallText(text: LanguageStringKeys.instance.save.tr, color: Colors.grey),
),
SizedBox(height: Dimensions.height15),
],
),
),
),
),
),
),
);
}
}
Hello guys I want to make dropdown menu changes when i change my option example when select failed changes to failed I made the code
onChanged: (selectedItem) {
setState(() {
setPassing(selectedItem);
});
},
instead of
onChanged: (selectedItem) {
setState(() {
debugPrint("User Select ${selectedItem}");
});
},
but it says The argument type 'Object?' can't be assigned to the parameter type 'String" and if I used the old code it don't make error but I can't change my selection and it is always successed this is the code of this page
import 'package:flutter/material.dart';
import 'dart:async';
import 'package:students/models/student.dart';
import 'package:students/utilities/sql_helper.dart';
import 'package:sqflite/sqflite.dart';
import 'students_list.dart';
class StudentDetail extends StatefulWidget {
String screenTitle;
late Student student;
StudentDetail(this.student, this.screenTitle);
#override
State<StatefulWidget> createState() {
// TODO: implement createState
return Students(this.student, screenTitle);
}
}
class Students extends State<StudentDetail> {
static var _status = ["successed", "failed"];
late String screenTitle;
late Student student;
SQL_Helper helper = new SQL_Helper();
Students(this.student, this.screenTitle);
TextEditingController studentName = new TextEditingController();
TextEditingController studentDetail = new TextEditingController();
#override
Widget build(BuildContext context) {
TextStyle textStyle = TextStyle();
studentName.text = student.name;
studentDetail.text = student.description;
// TODO: implement build
return WillPopScope(
child: Scaffold(
appBar: AppBar(
title: Text(screenTitle),
leading: IconButton(
onPressed: () {
goback();
},
icon: Icon(Icons.arrow_back_ios)),
),
body: Padding(
padding: EdgeInsets.only(top: 15.0, left: 10.0, right: 10.0),
child: ListView(
children: <Widget>[
ListTile(
title: DropdownButton(
items: _status.map((String dropDownItem) {
return DropdownMenuItem<String>(
value: dropDownItem,
child: Text(dropDownItem),
);
}).toList(),
style: textStyle,
value: getPassing(student.pass),
onChanged: (selectedItem) {
setState(() {
setPassing(selectedItem);
});
},
),
),
Padding(
padding: EdgeInsets.only(top: 15.0, bottom: 15.0),
child: TextField(
controller: studentName,
style: textStyle,
onChanged: (value) {
student.name = value;
},
decoration: InputDecoration(
labelText: "Name :",
labelStyle: textStyle,
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(5.0),
)),
),
),
Padding(
padding: EdgeInsets.only(top: 15.0, bottom: 15.0),
child: TextField(
controller: studentDetail,
style: textStyle,
onChanged: (value) {
student.description = value;
},
decoration: InputDecoration(
labelText: "Description :",
labelStyle: textStyle,
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(5.0),
)),
),
),
Padding(
padding: EdgeInsets.only(top: 15.0, bottom: 15.0),
child: Row(
children: <Widget>[
Expanded(
child: ElevatedButton(
style: ButtonStyle(
//todo
// color: Theme.of(context).primaryColorDark,
// textColor: Theme.of(context).primaryColorLight,
),
child: Text(
'SAVE',
textScaleFactor: 1.5,
),
onPressed: () {
setState(() {
debugPrint("User Click SAVED");
});
},
),
),
Container(
width: 5.0,
),
Expanded(
child: ElevatedButton(
style: ButtonStyle(
//todo
// color: Theme.of(context).primaryColorDark,
// textColor: Theme.of(context).primaryColorLight,
),
child: Text(
'Delete',
textScaleFactor: 1.5,
),
onPressed: () {
setState(() {
debugPrint("User Click Delete");
});
},
),
),
],
),
)
],
),
),
),
onWillPop: null);
}
void goback() {
Navigator.pop(context);
}
void setPassing(String value) {
switch (value) {
case "successed":
student.pass = 1;
break;
case "failed":
student.pass = 2;
break;
}
}
String getPassing(int value) {
late String pass = _status[0];
switch (value) {
case 1:
pass = _status[0];
break;
case 2:
pass = _status[1];
break;
}
return pass;
}
}
and this is the link of the entire code
https://github.com/abdelrahman992-cpu/stuothis
Add the explicit type (in this case, it is String?) on the onChanged arguments like so:
onChanged: (String? selectedItem) {
setState(() {
setPassing(selectedItem!);
});
},
I am very new to Flutter/Dart, so please forgive my ignorance and please explain everything to me like I am a five year old.
I have a screen on my app where I would like users to have two options: enter text using a textfield or select an option from a dropdown menu. Whichever they choose will be placed on a to-do list.
However, I can't seem to figure out how to get the selection from the DropdownButton widget to be saved to the to-do list the same way a textfield entry would be.
Below is my code for the screen where new items are entered.
import 'package:provider/provider.dart';
import 'task_data.dart';
class AddTaskScreen extends StatelessWidget {
#override
Widget build(BuildContext context) {
String newTaskTitle = '';
String _dropdownValue = '';
return Container(
color: const Color(0xFF757575),
child: Container(
decoration: const BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.only(
topLeft: Radius.circular(20.0), topRight: Radius.circular(20.0)),
),
padding: const EdgeInsets.symmetric(horizontal: 60.0, vertical: 30.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
const Text(
'Add a Task',
textAlign: TextAlign.center,
style: TextStyle(
color: Colors.blue,
fontSize: 30.0,
fontWeight: FontWeight.w500,
),
),
TextField(
autofocus: true,
textAlign: TextAlign.center,
style: const TextStyle(
fontSize: 25.0,
),
onChanged: (newText) {
newTaskTitle = newText;
},
),
TaskSelect(),
const SizedBox(
height: 20.0,
),
MaterialButton(
onPressed: () {
Provider.of<TaskData>(context, listen: false)
.addTask(newTaskTitle);
Navigator.pop(context);
},
color: Colors.blue,
child: const Text(
'Add',
style: TextStyle(
fontSize: 20.0,
),
),
textColor: Colors.white,
height: 50.0,
)
],
),
),
);
}
}
class TaskSelect extends StatefulWidget {
const TaskSelect({Key? key}) : super(key: key);
#override
State<TaskSelect> createState() => _TaskSelectState();
}
class _TaskSelectState extends State<TaskSelect> {
String dropdownValue = 'Select a task';
String newTaskTitle = '';
#override
Widget build(BuildContext context) {
return DropdownButton<String>(
value: dropdownValue,
icon: const Icon(Icons.arrow_downward),
elevation: 16,
style: const TextStyle(color: Colors.blueAccent),
underline: Container(
height: 2,
color: Colors.blueAccent,
),
onChanged: (String? newValue) {
setState(() {dropdownValue = newValue!;});
newTaskTitle = dropdownValue;
},
items: <String>[
'Task 1',
'Task 2',
'Task 3',
]
.map<DropdownMenuItem<String>>((String value) {
return DropdownMenuItem<String>(
value: value,
child: Text(value),
);
}).toList(),
);
}
}
Your problem is how to access the value selected from the other class
you can achieve that in many ways
one is to make the widget accept a variable (which is your titleText) and when it's changed in that class (widget) (TaskSelcted) it will change the variable value in the other class (widget)(AddTaskScreen)
class TaskSelect extends StatefulWidget {
//Telling the class you will get a value of string when ever someone used ue
String? taskTitle;
TaskSelect({Key? key, required this.taskTitle}) : super(key: key);
#override
State<TaskSelect> createState() => _TaskSelectState();
}
.
//Telling the class here you are being used, this is the value you are promised to get. you can change its value as i tell you
TaskSelect(newTaskTitle),
const SizedBox(
height: 20.0,
),
.
onChanged: (String? newValue) {
setState(() {dropdownValue = newValue!;});
//Change the variable you took to this value
widget.textTitle = dropdownValue;
}
I am design a screen in which I need to opening a drop down list when user click on textfield till now I am using CupertinoActionSheetAction sheet which is correctly working now I need to replace it with DropdownButton but when I am doing it is not displaying on screen I don't know why.
Here is my code focus on line number 136 (function for CupertinoActionSheetAction is working code) and line 138 where (function for drop not working code) according to me may be it due to build context but I m not sure how to use 'build context' in this context can any one help me out to fix that.
Thanks in advance, And any suggestion for making my code more reusable will be helpful as well :)
import 'dart:ffi';
import 'package:fleet_management/AppContants/Contants.dart';
import 'package:fleet_management/Controllers/NewFuelExpenseController.dart';
import 'package:fleet_management/Models/NewFuelExpenseModel.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
class AddFuelView extends StatefulWidget {
const AddFuelView({Key? key}) : super(key: key);
#override
_AddFuelView createState() {
return _AddFuelView();
}
}
// MyTripHistoryView
class _AddFuelView extends State<AddFuelView> {
NewFuelExpenseModel fuelExpense =
NewFuelExpenseController().getNewFuelExpense();
DateTime _selectedDate = DateTime.now();
String dropdownvalue = 'Item 1';
// List of items in our dropdown menu
var items = [
'Item 1',
'Item 2',
'Item 3',
'Item 4',
'Item 5',
];
TextStyle _titleTextStyle = const TextStyle();
TextStyle _valueTextStyle = const TextStyle();
final GlobalKey newFuelExpenseFormField = GlobalKey<FormState>();
final TextEditingController _dateEditingController = TextEditingController();
final TextEditingController _priceTextEditingController =
TextEditingController();
final TextEditingController _gallonsTextEditingController =
TextEditingController();
final TextEditingController _totalTextEditingController =
TextEditingController();
final TextEditingController _odometerTextEditingController =
TextEditingController();
final TextEditingController _fuelTypeTextEditingController =
TextEditingController();
final TextEditingController _vendorTextEditingController =
TextEditingController();
#override
void initState() {
super.initState();
_titleTextStyle =
const TextStyle(fontSize: 16, fontWeight: FontWeight.w600);
_valueTextStyle = const TextStyle(
fontSize: 16, fontWeight: FontWeight.w600, color: Colors.black38);
_dateEditingController.text =
"${_selectedDate.day}-${_selectedDate.month}-${_selectedDate.year}";
}
#override
Widget build(BuildContext context) {
var scaffold = Scaffold(
appBar: AppBar(
title: Text(StringsConstants.newFuelExpense),
backgroundColor: AppColorsConstants.primaryColor,
actions: <Widget>[
FlatButton(
textColor: Colors.white,
onPressed: () {
print("SAVE Button Clicked");
},
child: Text("Save", style: _titleTextStyle),
),
],
),
body: SafeArea(
child: SingleChildScrollView(
child: Padding(
padding: const EdgeInsets.all(16),
child: Form(
key: newFuelExpenseFormField,
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
children: [
showDateRow(context),
addTextFieldInput(
StringsConstants.priceGallon,
"\u{20B9}0.00",
false,
_priceTextEditingController,
TextInputType.datetime,
null,
null),
addTextFieldInput(
StringsConstants.gallons,
"",
false,
_gallonsTextEditingController,
TextInputType.number,
null,
null),
addTextFieldInput(
StringsConstants.total,
"\u{20B9}0.00",
false,
_totalTextEditingController,
TextInputType.number,
null,
null),
addTextFieldInput(
StringsConstants.odometer,
"",
false,
_odometerTextEditingController,
TextInputType.number,
null,
null),
// show action sheet
addTextFieldInput(
StringsConstants.fuelType,
"",
true,
_fuelTypeTextEditingController,
TextInputType.none,
null, () {
// Working. - >>>> HERE <<<<<
showActionSheet(context);
// Not Working >>>> HERE <<<<< Uncomment following function before
// showDropDown();
}),
addTextFieldInput(
StringsConstants.vendor,
"",
false,
_vendorTextEditingController,
TextInputType.text,
null,
null),
const SizedBox(
height: 50,
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
ElevatedButton(
onPressed: () {
print("Submit button pressed!");
},
style: ElevatedButton.styleFrom(
padding: const EdgeInsets.symmetric(horizontal: 24),
primary: AppColorsConstants.primaryColor,
textStyle:
const TextStyle(fontWeight: FontWeight.bold),
),
child: Text(StringsConstants.submit)),
ElevatedButton(
onPressed: () {
print("Cancel button pressed!");
},
style: ElevatedButton.styleFrom(
padding: const EdgeInsets.symmetric(horizontal: 24),
primary: AppColorsConstants.primaryColor,
textStyle:
const TextStyle(fontWeight: FontWeight.bold),
),
child: Text(StringsConstants.cancel))
],
)
],
),
),
),
),
),
);
return scaffold;
}
void showDropDown() {
DropdownButton<String>(
items: <String>['A', 'B', 'C', 'D'].map((String value) {
return DropdownMenuItem<String>(
value: value,
child: Text(value),
);
}).toList(),
onChanged: (_) {},
);
}
Future<dynamic> showActionSheet(BuildContext context) {
return showCupertinoModalPopup(
context: context,
builder: (BuildContext context) => CupertinoActionSheet(
title: const Text('Choose Options'),
actions: <Widget>[
CupertinoActionSheetAction(
child: const Text('Oil'),
onPressed: () {
_fuelTypeTextEditingController.text = "Oil";
Navigator.pop(context, 'Oil');
},
),
CupertinoActionSheetAction(
child: const Text('Petrol'),
onPressed: () {
_fuelTypeTextEditingController.text = "Petrol";
Navigator.pop(context, 'Petrol');
},
),
CupertinoActionSheetAction(
child: const Text('diesel'),
onPressed: () {
_fuelTypeTextEditingController.text = "diesel";
Navigator.pop(context, 'diesel');
},
)
],
cancelButton: CupertinoActionSheetAction(
child: const Text('Cancel'),
isDefaultAction: true,
onPressed: () {
Navigator.pop(context, 'Cancel');
},
)),
);
}
Container addTextFieldInput(
String title,
String initialValue,
bool isEditable,
TextEditingController textfieldController,
TextInputType keyboardType,
FormFieldValidator<String>? validator,
GestureTapCallback? tabCallback,
) {
return Container(
padding: const EdgeInsets.fromLTRB(0, 16, 0, 8),
child: SizedBox(
child: TextFormField(
onTap: tabCallback,
keyboardType: keyboardType,
cursorHeight: 16,
cursorWidth: 1.4,
readOnly: isEditable,
controller: textfieldController,
validator: validator,
decoration: InputDecoration(
isDense: true,
floatingLabelStyle:
TextStyle(color: AppColorsConstants.primaryColor),
labelText: title,
focusedBorder: OutlineInputBorder(
borderSide: BorderSide(
color: AppColorsConstants.primaryColor, width: 1.5),
),
enabledBorder: const OutlineInputBorder(
borderSide: BorderSide(color: Colors.black38, width: 1.5),
),
border: const OutlineInputBorder()),
style: const TextStyle(fontSize: 18),
cursorColor: Colors.black38,
showCursor: true,
autofocus: true,
),
),
);
}
Container showDateRow(BuildContext context) {
return Container(
child: TextFormField(
onTap: () => {_selectDate(context)},
cursorHeight: 16,
cursorWidth: 1.4,
readOnly: true,
enableInteractiveSelection: false,
controller: _dateEditingController,
decoration: InputDecoration(
isDense: true,
labelStyle: const TextStyle(color: Colors.orangeAccent),
labelText: StringsConstants.date,
focusedBorder: const OutlineInputBorder(
borderSide: BorderSide(color: Colors.orangeAccent, width: 1.5),
),
enabledBorder: const OutlineInputBorder(
borderSide: BorderSide(color: Colors.black38, width: 1.5),
),
border: const OutlineInputBorder()),
style: const TextStyle(fontSize: 18),
cursorColor: Colors.black38,
showCursor: true,
autofocus: true,
),
);
}
Future<void> _selectDate(BuildContext context) async {
final DateTime? picked = await showDatePicker(
context: context,
initialDate: _selectedDate,
firstDate: DateTime(1990),
lastDate: DateTime.now());
if (picked != null && picked != _selectedDate) {
setState(() {
_selectedDate = picked;
this._dateEditingController.text =
"${_selectedDate.day}-${_selectedDate.month}-${_selectedDate.year}";
});
}
}
}
For DropDown in flutter you need
an initail value,
a list to be shown just
String selectedvalue='myvalue';
/// be sure you add the variable value in the 0 index of you list other wise it will thrown error or exception..
List<String> myList=[
'myvalue',/// the value is same as variable value
'othe value', ....
];
DropDownButton(
onChanged: (resultValue){
/// you can get selected value from here
},
items: myList.map((e){
retrun DropdownMenuItem(
value: e,
child: Text(e));
}).toList(),
value: selectedvalue,
),
You can use DropdownButtonFormField in place of TextFormField and can make some style related changes per your requirement.
class MyWidget extends StatelessWidget {
String selectedValue = "USA";
List<DropdownMenuItem<String>> get dropdownItems{
List<DropdownMenuItem<String>> menuItems = [
DropdownMenuItem(child: Text("USA"),value: "USA"),
DropdownMenuItem(child: Text("Canada"),value: "Canada"),
DropdownMenuItem(child: Text("Brazil"),value: "Brazil"),
DropdownMenuItem(child: Text("England"),value: "England"),
];
return menuItems;
}
#override
Widget build(BuildContext context) {
return DropdownButtonFormField(
decoration: InputDecoration(
enabledBorder: OutlineInputBorder(
borderSide: BorderSide(color: Colors.blue, width: 2),
borderRadius: BorderRadius.circular(20),
),
border: OutlineInputBorder(
borderSide: BorderSide(color: Colors.blue, width: 2),
borderRadius: BorderRadius.circular(20),
),
filled: true,
fillColor: Colors.blueAccent,
),
dropdownColor: Colors.blueAccent,
value: selectedValue,
onChanged: (String? newValue) {
selectedValue = newValue!;
},
items: dropdownItems);
}
}
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;
});
},
),
),
),
);
}
}