'Drop down widget is not showing in flutter
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}";
});
}
}
}
Solution 1:[1]
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,
),
Solution 2:[2]
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);
}
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | Ameer Hamza |
Solution 2 | Bhoomika Harkhani |