Drop down widget is not showing in flutter - 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}";
});
}
}
}

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);
}
}

Related

Flutter there should be exactly one item with [DropdownButton]'s value: Dubai. Either zero or 2 or more [DropdownMenuItem]s were detected

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),
],
),
),
),
),
),
),
);
}
}

How to collapse the ExpansionTile on button click? - Flutter

I'm opening up a form to enter the details and close it upon filling everything and submitting it, but only the trailing icon is getting changed, also I'm trying to set the changes in the onExpansionChanged but not reflecting in the UI.
Updated Code
Scaffold(
backgroundColor: Colors.grey.shade200,
appBar: AppBar(
title: TextButton(
child: Text(count.toString()),
onPressed: () {
Navigator.push(context,
MaterialPageRoute(builder: (_) => RegisterLetterBookedListScreen()));
},
),
backgroundColor: ColorConstants.kPrimaryColor,
elevation: 0,
),
floatingActionButton: FloatingActionButton(
onPressed: () {
MotionToast.success(
title: 'Amount to be Collected',
titleStyle: TextStyle(fontWeight: FontWeight.bold),
description: '\u{20B9} $amountToBeCollected',
descriptionStyle: TextStyle(fontSize: 20, fontWeight: FontWeight.w500),
layoutOrientation: ORIENTATION.LTR,
animationType: ANIMATION.FROM_LEFT,
width: 300,
).show(context);
},
child: Text(
'\u{20B9} $amountToBeCollected',
style: TextStyle(fontSize: 20),
),
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(10)),
),
body: Padding(
padding: const EdgeInsets.all(20.0),
child: SingleChildScrollView(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
//Article Details
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
//Sender Details
ExpansionTile(
key: GlobalKey(),
trailing: (senderExpansion == false)
? Icon(
MdiIcons.toggleSwitchOffOutline,
size: 40,
color: Colors.black54,
)
: Icon(MdiIcons.toggleSwitchOutline, size: 40, color: Colors.red),
onExpansionChanged: (value) {
senderExpansion = value;
},
maintainState: true,
initiallyExpanded: senderExpansion,
title: Text(
'Sender Details',
style: TextStyle(
fontWeight: FontWeight.bold,
color: senderHeadingColor,
fontSize: 20,
letterSpacing: 1),
),
children: [
Column(
children: [
CInputForm(
readOnly: false,
iconData: Icons.person,
labelText: 'Name *',
controller: senderNameController,
textType: TextInputType.text,
typeValue: 'Name',
focusNode: senderNameFocusNode,
),
CInputForm(
readOnly: false,
iconData: MdiIcons.home,
labelText: 'Address *',
controller: senderAddressController,
textType: TextInputType.multiline,
typeValue: 'Address',
focusNode: senderAddressFocusNode,
),
Card(
elevation: 0,
child: TypeAheadFormField(
textFieldConfiguration: TextFieldConfiguration(
style: TextStyle(color: Colors.blueGrey),
controller: senderPinCodeCityController,
autofocus: false,
decoration: InputDecoration(
prefixIcon: Icon(
Icons.location_on_outlined,
color: Colors.blueGrey,
),
fillColor: Colors.white,
filled: true,
enabledBorder: OutlineInputBorder(
borderSide: BorderSide(color: Colors.white),
),
labelText: 'Pincode/Office Name *',
labelStyle: TextStyle(
color: ColorConstants.kAmberAccentColor),
border: OutlineInputBorder(
borderSide: BorderSide(color: Colors.white)))),
onSuggestionSelected:
(Map<String, String> suggestion) async {
senderPinCodeCityController.text = suggestion['pinCode']!;
senderCityController.text = suggestion['city']!;
senderStateController.text = suggestion['state']!;
},
itemBuilder: (context, Map<String, String> suggestion) {
return ListTile(
title: Text(suggestion['officeName']! +
", " +
suggestion['pinCode']!),
);
},
suggestionsCallback: (pattern) async {
return await FetchPin.getSuggestions(pattern);
},
validator: (value) {
if (value!.isEmpty) {
issPin = false;
isLoading = false;
}
},
),
),
Visibility(
visible: issPin == false ? senderPinCodeCityController.text.isEmpty ? true : false : false,
child: Align(
alignment: Alignment.topLeft,
child: Padding(
padding: const EdgeInsets.only(left: 17.0),
child: Text('Select a Pincode/Office name', style: TextStyle(fontSize: 10, color: ColorConstants.kPrimaryColor),),
)),
),
Visibility(
visible:
senderPinCodeCityController.text.isEmpty ? false : true,
child: CInputForm(
readOnly: true,
iconData: Icons.location_city,
labelText: 'City',
controller: senderCityController,
textType: TextInputType.text,
typeValue: 'City',
focusNode: senderPinCodeFocusNode,
),
),
Visibility(
visible:
senderPinCodeCityController.text.isEmpty ? false : true,
child: CInputForm(
readOnly: true,
iconData: Icons.location_city,
labelText: 'State',
controller: senderStateController,
textType: TextInputType.text,
typeValue: 'City',
focusNode: senderPinCodeFocusNode,
),
),
CInputForm(
readOnly: false,
iconData: MdiIcons.cellphone,
labelText: 'Mobile Number',
controller: senderMobileNumberController,
textType: TextInputType.number,
typeValue: 'MobileNumber',
focusNode: senderMobileFocusNode,
),
CInputForm(
readOnly: false,
iconData: MdiIcons.email,
labelText: 'Email',
controller: senderEmailController,
textType: TextInputType.emailAddress,
typeValue: 'Email',
focusNode: senderEmailFocusNode,
),
],
)
],
),
//Addressee Details
ExpansionTile(
trailing: (addresseeExpansion == false)
? Icon(
MdiIcons.toggleSwitchOffOutline,
size: 40,
color: Colors.black54,
)
: Icon(MdiIcons.toggleSwitchOutline, size: 40, color: Colors.red),
onExpansionChanged: (value) {
addresseeExpansion = value;
},
maintainState: true,
title: Text('Addressee Details',
style: TextStyle(
fontWeight: FontWeight.bold,
color: addresseeHeadingColor,
fontSize: 20,
letterSpacing: 1)),
children: [
Column(
children: [
CInputForm(
readOnly: false,
iconData: Icons.person,
labelText: 'Name *',
controller: addresseeNameController,
textType: TextInputType.text,
typeValue: 'Name',
focusNode: addresseeNameFocusNode,
),
CInputForm(
readOnly: false,
iconData: MdiIcons.home,
labelText: 'Address *',
controller: addresseeAddressController,
textType: TextInputType.multiline,
typeValue: 'Address',
focusNode: addresseeAddressFocusNode,
),
Card(
elevation: 0,
child: TypeAheadFormField(
textFieldConfiguration: TextFieldConfiguration(
style: TextStyle(color: Colors.blueGrey),
controller: addresseePinCodeCityController,
autofocus: false,
decoration: InputDecoration(
prefixIcon: Icon(
Icons.location_on_outlined,
color: Colors.blueGrey,
),
fillColor: Colors.white,
filled: true,
enabledBorder: OutlineInputBorder(
borderSide: BorderSide(color: Colors.white),
),
labelText: 'Pincode/Office Name *',
labelStyle: TextStyle(
color: ColorConstants.kAmberAccentColor),
border: OutlineInputBorder(
borderSide: BorderSide(color: Colors.white)))),
onSuggestionSelected:
(Map<String, String> suggestion) async {
addresseePinCodeCityController.text =
suggestion['pinCode']!;
addresseeCityController.text = suggestion['city']!;
addresseeStateController.text = suggestion['state']!;
},
itemBuilder: (context, Map<String, String> suggestion) {
return ListTile(
title: Text(suggestion['officeName']! +
", " +
suggestion['pinCode']!),
);
},
suggestionsCallback: (pattern) async {
return await FetchPin.getSuggestions(pattern);
},
validator: (value) {
if (value!.isEmpty) {
isLoading = false;
isaPin = false;
}
},
),
),
Visibility(
visible: isaPin == false ? addresseePinCodeCityController.text.isEmpty ? true : false : false,
child: Align(
alignment: Alignment.topLeft,
child: Padding(
padding: const EdgeInsets.only(left: 17.0),
child: Text('Select a Pincode/Office name', style: TextStyle(fontSize: 10, color: ColorConstants.kPrimaryColor),),
)),
),
Visibility(
visible: addresseePinCodeCityController.text.isEmpty
? false
: true,
child: CInputForm(
readOnly: true,
iconData: Icons.location_city,
labelText: 'City',
controller: addresseeCityController,
textType: TextInputType.text,
typeValue: 'City',
focusNode: addresseePinCodeFocusNode,
),
),
Visibility(
visible: addresseePinCodeCityController.text.isEmpty
? false
: true,
child: CInputForm(
readOnly: true,
iconData: Icons.location_city,
labelText: 'State',
controller: addresseeStateController,
textType: TextInputType.text,
typeValue: 'State',
focusNode: addresseePinCodeFocusNode,
),
),
CInputForm(
readOnly: false,
iconData: MdiIcons.cellphone,
labelText: 'Mobile Number',
controller: addresseeMobileNumberController,
textType: TextInputType.number,
typeValue: 'MobileNumber',
focusNode: addresseeMobileFocusNode,
),
CInputForm(
readOnly: false,
iconData: MdiIcons.email,
labelText: 'Email',
controller: addresseeEmailController,
textType: TextInputType.emailAddress,
typeValue: 'Email',
focusNode: addresseeEmailFocusNode,
),
],
),
],
),
//Submit
Padding(
padding: const EdgeInsets.all(8.0),
child: Center(
child: ElevatedButton(
style: ButtonStyle(
backgroundColor:
MaterialStateProperty.all<Color>(Colors.white),
shape: MaterialStateProperty.all<RoundedRectangleBorder>(
RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10),
side: BorderSide(color: Colors.blueGrey)))),
onPressed: () async {
setState(() {
senderExpansion = !senderExpansion;
addresseeExpansion = !addresseeExpansion;
});
final ifPresent = await RegisterLetterTable()
.select()
.ArticleNumber
.equals(articleNumberController.text)
.toMapList();
if (ifPresent.isNotEmpty) {
ScaffoldMessenger.of(context).showSnackBar(SnackBar(
content: Text('Article already scanned'),
behavior: SnackBarBehavior.floating,
));
} else {
if (articleNumberController.text.isEmpty) {
setState(() {
articleNumberFocusNode.requestFocus();
});
} else if (weightController.text.isEmpty) {
setState(() {
weightFocusNode.requestFocus();
});
} else if (insuranceCheck == true) {
if (insuranceController.text.isEmpty)
insuranceFocusNode.requestFocus();
} else if (valuePayableCheck == true) {
if (valuePayablePostController.text.isEmpty)
valuePayableFocusNode.requestFocus();
}
if (senderNameController.text.isEmpty ||
senderAddressController.text.isEmpty ||
senderPinCodeCityController.text.isEmpty) {
setState(() {
senderExpansion = true;
});
if (addresseeNameController.text.isEmpty ||
addresseeAddressController.text.isEmpty ||
addresseePinCodeCityController.text.isEmpty) {
setState(() {
addresseeExpansion = true;
});
} else
setState(() {
addresseeExpansion = false;
});
} else
senderExpansion = false;
if (addresseeNameController.text.isEmpty ||
addresseeAddressController.text.isEmpty ||
addresseePinCodeCityController.text.isEmpty) {
setState(() {
addresseeExpansion = true;
});
} else
setState(() {
addresseeExpansion = false;
});
if (formGlobalKey.currentState!.validate()) {
formGlobalKey.currentState!.save();
showDialog<void>(
context: context,
barrierDismissible: false,
builder: (BuildContext context) {
return ConformationDialog(
articleNumber: articleNumberController.text,
weight: weightController.text,
prepaidAmount: prepaidAmountController.text,
acknowledgement: acknowledgementCheck,
insurance: insuranceCheck == true
? insuranceController.text
: '',
valuePayablePost: valuePayableCheck == true
? valuePayablePostController.text
: '',
amountToBeCollected:
amountToBeCollectedController.text,
senderName: senderNameController.text,
senderAddress: senderAddressController.text,
senderPinCode: senderPinCodeCityController.text,
senderCity: senderCityController.text,
senderState: senderStateController.text,
senderMobileNumber:
senderMobileNumberController.text,
senderEmail: senderEmailController.text,
addresseeName: addresseeNameController.text,
addresseeAddress: addresseeAddressController.text,
addresseePinCode:
addresseePinCodeCityController.text,
addresseeCity: addresseeCityController.text,
addresseeState: addresseeStateController.text,
addresseeMobileNumber:
addresseeMobileNumberController.text,
addresseeEmail: addresseeEmailController.text,
function: () {
Navigator.of(context).pop();
printFunction();
});
});
}
}
},
child: Padding(
padding: const EdgeInsets.all(8.0),
child: new Text(
'SUBMIT',
overflow: TextOverflow.ellipsis,
style: TextStyle(color: ColorConstants.kAmberAccentColor),
),
),
),
),
)
],
),
),
))
checkout below code it may help you,
class TestExpanTile extends StatefulWidget {
#override
TestExpanTileState createState() => new TestExpanTileState();
}
class TestExpanTileState extends State<TestExpanTile> {
String senderDet = 'Sender Details ';
bool formOpenFlag = true;
#override
Widget build(BuildContext context) {
return new MaterialApp(
home: new Scaffold(
appBar: new AppBar(
title: const Text('ExpansionTile'),
),
body: new ExpansionTile(
key: GlobalKey(),
initiallyExpanded: formOpenFlag,
onExpansionChanged: (val) {
formOpenFlag = val; // update here on change
},
title: new Text(this.senderDet),
backgroundColor: Theme.of(context).accentColor.withOpacity(0.025),
children: <Widget>[
new ListTile(
title: const Text('Your Filling Form goes here'),
onTap: () {},
),
RaisedButton(
onPressed: () {
setState(() {
formOpenFlag = !formOpenFlag;
});
},
child: Text("Close Tile On Submit"),
)
],
),
),
);
}
}
Since your using Multiple ExpansionTiles, as said by #Jai Techie you need a key to control its state, but as per my knowledge we cannot provide the state of the ExpansionTile as the GlobalKey, so in order to acheive it create a new CustomExpansionTile.
import 'package:flutter/material.dart';
class FormExpansionTileCard extends StatefulWidget {
const FormExpansionTileCard({
Key? key,
this.leading,
required this.title,
this.subtitle,
this.onExpansionChanged,
this.children = const <Widget>[],
this.trailing,
this.borderRadius = const BorderRadius.all(Radius.circular(8.0)),
this.elevation = 2.0,
this.initialElevation = 0.0,
this.initiallyExpanded = false,
this.initialPadding = EdgeInsets.zero,
this.finalPadding = const EdgeInsets.only(bottom: 6.0),
this.contentPadding,
this.baseColor,
this.expandedColor,
this.expandedTextColor,
this.duration = const Duration(milliseconds: 200),
this.elevationCurve = Curves.easeOut,
this.heightFactorCurve = Curves.easeIn,
this.turnsCurve = Curves.easeIn,
this.colorCurve = Curves.easeIn,
this.paddingCurve = Curves.easeIn,
this.isThreeLine = false,
this.shadowColor = const Color(0xffaaaaaa),
this.animateTrailing = false,
}) : assert(initiallyExpanded != null),
super(key: key);
final bool isThreeLine;
final Widget? leading;
final Widget title;
final Widget? subtitle;
final ValueChanged<bool>? onExpansionChanged;
final List<Widget> children;
final Widget? trailing;
final bool animateTrailing;
final BorderRadiusGeometry borderRadius;
final double elevation;
final double initialElevation;
final Color shadowColor;
final bool initiallyExpanded;
final EdgeInsetsGeometry initialPadding;
final EdgeInsetsGeometry finalPadding;
final EdgeInsetsGeometry? contentPadding;
final Color? baseColor;
final Color? expandedColor;
final Color? expandedTextColor;
final Duration duration;
final Curve elevationCurve;
final Curve heightFactorCurve;
final Curve turnsCurve;
final Curve colorCurve;
final Curve paddingCurve;
#override
FormExpansionTileCardState createState() => FormExpansionTileCardState();
}
class FormExpansionTileCardState extends State<FormExpansionTileCard>
with SingleTickerProviderStateMixin {
static final Animatable<double> _halfTween =
Tween<double>(begin: 0.0, end: 0.5);
final ColorTween _headerColorTween = ColorTween();
final ColorTween _iconColorTween = ColorTween();
final ColorTween _materialColorTween = ColorTween();
late EdgeInsetsTween _edgeInsetsTween;
late Animatable<double> _elevationTween;
late Animatable<double> _heightFactorTween;
late Animatable<double> _turnsTween;
late Animatable<double> _colorTween;
late Animatable<double> _paddingTween;
late AnimationController _controller;
late Animation<double> _iconTurns;
late Animation<double> _heightFactor;
late Animation<double> _elevation;
late Animation<Color?> _headerColor;
late Animation<Color?> _iconColor;
late Animation<Color?> _materialColor;
late Animation<EdgeInsets> _padding;
bool _isExpanded = false;
#override
void initState() {
super.initState();
_edgeInsetsTween = EdgeInsetsTween(
begin: widget.initialPadding as EdgeInsets?,
end: widget.finalPadding as EdgeInsets?,
);
_elevationTween = CurveTween(curve: widget.elevationCurve);
_heightFactorTween = CurveTween(curve: widget.heightFactorCurve);
_colorTween = CurveTween(curve: widget.colorCurve);
_turnsTween = CurveTween(curve: widget.turnsCurve);
_paddingTween = CurveTween(curve: widget.paddingCurve);
_controller = AnimationController(duration: widget.duration, vsync: this);
_heightFactor = _controller.drive(_heightFactorTween);
_iconTurns = _controller.drive(_halfTween.chain(_turnsTween));
_headerColor = _controller.drive(_headerColorTween.chain(_colorTween));
_materialColor = _controller.drive(_materialColorTween.chain(_colorTween));
_iconColor = _controller.drive(_iconColorTween.chain(_colorTween));
_elevation = _controller.drive(
Tween<double>(begin: widget.initialElevation, end: widget.elevation)
.chain(_elevationTween));
_padding = _controller.drive(_edgeInsetsTween.chain(_paddingTween));
_isExpanded = PageStorage.of(context)?.readState(context) as bool? ??
widget.initiallyExpanded;
if (_isExpanded) _controller.value = 1.0;
}
#override
void dispose() {
_controller.dispose();
super.dispose();
}
// Credit: Simon Lightfoot - https://stackoverflow.com/a/48935106/955974
void _setExpansion(bool shouldBeExpanded) {
if (shouldBeExpanded != _isExpanded) {
setState(() {
_isExpanded = shouldBeExpanded;
if (_isExpanded) {
_controller.forward();
} else {
_controller.reverse().then<void>((void value) {
if (!mounted) return;
setState(() {
// Rebuild without widget.children.
});
});
}
PageStorage.of(context)?.writeState(context, _isExpanded);
});
if (widget.onExpansionChanged != null)
widget.onExpansionChanged!(_isExpanded);
}
}
void expand() {
_setExpansion(true);
}
void collapse() {
_setExpansion(false);
}
void toggleExpansion() {
_setExpansion(!_isExpanded);
}
Widget _buildChildren(BuildContext context, Widget? child) {
return Padding(
padding: _padding.value,
child: Material(
color: Colors.grey[200],
borderRadius: widget.borderRadius,
elevation: 0,
shadowColor: widget.shadowColor,
child: Container(
child: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
InkWell(
customBorder:
RoundedRectangleBorder(borderRadius: widget.borderRadius),
onTap: toggleExpansion,
child: ListTileTheme.merge(
iconColor: _iconColor.value,
textColor: _headerColor.value,
child: Padding(
padding: const EdgeInsets.all(2.0),
child: ListTile(
isThreeLine: widget.isThreeLine,
contentPadding: widget.contentPadding,
leading: widget.leading,
title: widget.title,
subtitle: widget.subtitle,
trailing: RotationTransition(
turns: widget.trailing == null || widget.animateTrailing
? _iconTurns
: AlwaysStoppedAnimation(0),
child: widget.trailing ?? Icon(Icons.expand_more),
),
),
),
),
),
ClipRect(
child: Align(
heightFactor: _heightFactor.value,
child: child,
),
),
],
),
),
),
);
}
#override
void didChangeDependencies() {
final ThemeData theme = Theme.of(context);
_headerColorTween
..begin = theme.textTheme.subtitle1!.color
..end = widget.expandedTextColor ?? theme.accentColor;
_iconColorTween
..begin = theme.unselectedWidgetColor
..end = widget.expandedTextColor ?? theme.accentColor;
_materialColorTween
..begin = widget.baseColor ?? theme.canvasColor
..end = widget.expandedColor ?? theme.cardColor;
super.didChangeDependencies();
}
#override
Widget build(BuildContext context) {
final bool closed = !_isExpanded && _controller.isDismissed;
return AnimatedBuilder(
animation: _controller.view,
builder: _buildChildren,
child: closed ? null : Column(children: widget.children),
);
}
}
Initialize the key value in your dart file
final GlobalKey<FormExpansionTileCardState> cardA = new GlobalKey();
final GlobalKey<FormExpansionTileCardState> cardB = new GlobalKey();
//Sender Details
FormExpansionTileCard(
key: cardA,
trailing: (senderExpansion == false)
? Icon(
MdiIcons.toggleSwitchOffOutline,
size: 40,
color: Colors.black54,
)
: Icon(MdiIcons.toggleSwitchOutline, size: 40, color: Colors.red),
onExpansionChanged: (value) {
senderExpansion = value;
},
initiallyExpanded: senderExpansion,
title: Text(
'Sender Details',
style: TextStyle(
fontWeight: FontWeight.bold,
color: senderHeadingColor,
fontSize: 20,
letterSpacing: 1),
),
children: [
//...Your Widgets
],
),
//Addressee Details
FormExpansionTileCard(
key: cardB,
trailing: (senderExpansion == false)
? Icon(
MdiIcons.toggleSwitchOffOutline,
size: 40,
color: Colors.black54,
)
: Icon(MdiIcons.toggleSwitchOutline, size: 40, color: Colors.red),
onExpansionChanged: (value) {
addresseeExpansion = value;
},
initiallyExpanded: addresseeExpansion,
title: Text(
'AddresseeDetails',
style: TextStyle(
fontWeight: FontWeight.bold,
color: senderHeadingColor,
fontSize: 20,
letterSpacing: 1),
),
children: [
//...Your Widgets
],
),
I created a simple solution to this very problem. Hope this helps.
Solution: https://github.com/TreyThomas93/flutter-expansion-tile-demo

How to clear the dropdown button in flutter

im new in flutter and I create a drop down button fields in flutter for the record form. My question is when I click save in the record, how can I make the dropdown is clear (back to the first or no value) for now when I click save, it did not reset the drop down value (still have a value from previous record) And also when I click the clear button, how can I make the drop down is clear? Thanks
class RecordExpense extends StatefulWidget {
#override
_RecordExpenseState createState() => _RecordExpenseState();
}
class _RecordExpenseState extends State<RecordExpense> {
//DatabaseReference _ref;
final date = TextEditingController();
final currency = TextEditingController();
final category = TextEditingController();
final amount = TextEditingController();
final description = TextEditingController();
final FirebaseAuth _auth = FirebaseAuth.instance;
final databaseReference = FirebaseFirestore.instance;
GlobalKey<FormState> _formKey = GlobalKey<FormState>();
String _email, _password;
Future<String> getCurrentUID() async {
Future.value(FirebaseAuth.instance.currentUser);
//return uid;
}
#override
String selectCurrency;
String selectExpense;
final expenseSelected = TextEditingController();
final currencySelected = TextEditingController();
DateTime _selectedDate;
void initState(){
//_ref = FirebaseDatabase.instance.reference().child('Transaction');
}
Widget build(BuildContext context) {
//FirebaseFirestore firestore = FirebaseFirestore.instance;
//CollectionReference collect= firestore.collection("TransactionExpense");
final FirebaseAuth _auth = FirebaseAuth.instance;
final User user =_auth.currentUser;
final uid = user.uid;
String dates;
String amounts;
//String selectExpenses;
String descriptions;
return new Form(
child: SingleChildScrollView(
child: Padding(
padding: EdgeInsets.all(20.0),
child: Container(
child: Form(
key: _formKey,
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
Container(
child: TextFormField(
validator: (input) {
if (input.isEmpty) return 'Please fill up the text fields';
},
cursorColor: Colors.grey,
controller: date,
onTap: () {
_selectDate(context);
},
decoration: InputDecoration(
labelText: getTranslated((context), "date_text"),
labelStyle: TextStyle(
fontSize: 18.0, color: Colors.black),
hintText: getTranslated((context), "date_hint"),
enabledBorder: UnderlineInputBorder(
borderSide: BorderSide(color: secondary),
),
focusedBorder: UnderlineInputBorder(
borderSide: BorderSide(color: secondary),
),
),
),
),
SizedBox(height: 20),
Row(
children: <Widget> [
new Expanded(child: new DropdownButtonFormField<String>(
value: selectCurrency,
hint: Text(getTranslated((context), "currency_hint"),),
//controller: currencySelected,
//labelText: getTranslated((context), "currency_hint"),
//enabled: true,
//itemsVisibleInDropdown: 4,
//items: currencycategories,
onChanged: (salutation) =>
setState(() => selectCurrency = salutation),
validator: (value) => value == null ? 'Please fill up the drop down' : null,
items:
['IDR.', 'MYR', 'USD', 'CNY'].map<DropdownMenuItem<String>>((String value) {
return DropdownMenuItem<String>(
value: value,
child: Text(value),
);
}).toList(),
//flex: 2,
),
//value: selectCurrency,
//required: false,
),
new SizedBox(
width: 10.0,
),
new Expanded(child:
TextFormField(
validator: (input) {
if (input.isEmpty) return 'Please fill up the text fields';
},
cursorColor: Colors.grey,
controller: amount,
decoration: InputDecoration(
labelText: getTranslated((context), "amount_text"),
labelStyle: TextStyle(
fontSize: 18.0, color: Colors.black),
hintText: getTranslated((context), "amount_text"),
enabledBorder: UnderlineInputBorder(
borderSide: BorderSide(color: secondary),
),
focusedBorder: UnderlineInputBorder(
borderSide: BorderSide(color: secondary),
),
),
keyboardType: TextInputType.number,
),)
],
),
Container(
padding: EdgeInsets.only(top: 20.0),
child: DropdownButtonFormField <String>(
value: selectExpense,
hint: Text(getTranslated((context), "category_text"),),
//controller: currencySelected,
//labelText: getTranslated((context), "currency_hint"),
//enabled: true,
//itemsVisibleInDropdown: 4,
//items: currencycategories,
onChanged: (salutation) =>
setState(() => selectExpense = salutation),
validator: (value) => value == null ? 'Please fill up the drop down' : null,
items:
['Food.', 'Social Life', 'Transportation', 'Beauty', 'Household', 'Education', 'Health', 'Gift', 'Other'].map<DropdownMenuItem<String>>((String value) {
return DropdownMenuItem<String>(
value: value,
child: Text(value),
);
}).toList(),
//flex: 2,
),
),
SizedBox(height: 20),
Container(
//padding: EdgeInsets.all(20),
child: TextFormField(
validator: (input) {
if (input.isEmpty) return 'Please fill up the text fields';
},
cursorColor: Colors.grey,
controller: description,
maxLines: 2,
decoration: InputDecoration(
labelText: getTranslated((context), "description_text"),
labelStyle: TextStyle(
fontSize: 18.0, color: Colors.black),
hintText: getTranslated((context), "description_expense"),
enabledBorder: UnderlineInputBorder(
borderSide: BorderSide(color: secondary),
),
focusedBorder: UnderlineInputBorder(
borderSide: BorderSide(color: secondary),
),
),
),
),
Container(
padding: EdgeInsets.only(
top: 25.0, left: 20.0, right: 20.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Expanded(
child: ElevatedButton(
onPressed: () async {
if(!_formKey.currentState.validate()){
return;
}
_formKey.currentState.save();
await FirebaseFirestore.instance.collection('users').doc(userID).collection('TransactionExpense').add({
'date': date.text,
'currency': selectCurrency,
'amount': amount.text,
'category': selectExpense,
'description': description.text,
});
date.text = "";
amount.text = "";
description.text = "";
//selectCurrency = "";
//selectExpense = "";
/*
UserCredential _user =
await FirebaseAuth.instance.signInWithEmailAndPassword(email: _email, password: _password);
String _uid = _user.user.uid;
*/
//await FirebaseFirestore.instance.collection('TransactionExpense').doc(_uid).set({
/*
final FirebaseAuth _auth = FirebaseAuth
.instance;
final User user = _auth.currentUser;
final uid = user.uid;
await DatabaseService().updateData(
uid, date.text, amount.text,
selectExpense, description.text);
Navigator.pop(context);
*/
},
child: Text(
getTranslated((context), "save_button").toUpperCase(), style: TextStyle(
fontSize: 14,
)),
style: ButtonStyle(
padding: MaterialStateProperty.all<
EdgeInsets>(EdgeInsets.all(15)),
foregroundColor: MaterialStateProperty
.all<Color>(Colors.white),
backgroundColor: MaterialStateProperty
.all<Color>(Colors.pink),
shape: MaterialStateProperty.all<
RoundedRectangleBorder>(
RoundedRectangleBorder(
borderRadius: BorderRadius.circular(
15.0),
side: BorderSide(color: secondary)
),
),
),
),
),
SizedBox(width: 20, height: 10),
Expanded(
child: ElevatedButton(
onPressed: () {
clearButton();
},
child: Text(
getTranslated((context), "clear_button").toUpperCase(), style: TextStyle(
fontSize: 14
)),
style: ButtonStyle(
padding: MaterialStateProperty.all<
EdgeInsets>(EdgeInsets.all(15)),
foregroundColor: MaterialStateProperty
.all<Color>(Colors.white),
backgroundColor: MaterialStateProperty
.all<Color>(Colors.pink),
shape: MaterialStateProperty.all<
RoundedRectangleBorder>(
RoundedRectangleBorder(
borderRadius: BorderRadius.circular(
15.0),
side: BorderSide(color: secondary)
),
),
),
),
)
],
)
),
],
),
),
),
)
),
);
}
void clearButton(){
date.clear();
amount.clear();
category.clear();
description.clear();
//selectCurrency.clear();
}
_selectDate(BuildContext context) async {
DateTime newSelectedDate = await showDatePicker(
context: context,
initialDate: _selectedDate != null ? _selectedDate : DateTime.now(),
firstDate: DateTime(2000),
lastDate: DateTime(2040),
builder: (BuildContext context, Widget child) {
return Theme(
data: ThemeData.dark().copyWith(
colorScheme: ColorScheme.dark(
primary: secondary,
onPrimary: Colors.black,
surface: primary,
onSurface: Colors.white,
),
dialogBackgroundColor: Colors.black,
),
child: child,
);
});
if (newSelectedDate != null) {
_selectedDate = newSelectedDate;
date
..text = DateFormat.yMMMd().format(_selectedDate)
..selection = TextSelection.fromPosition(TextPosition(
offset: date.text.length,
affinity: TextAffinity.upstream));
}
}
}
class AlwaysDisabledFocusNode extends FocusNode {
#override
bool get hasFocus => false;
}
When the user taps on the save button the onPressed function is executed, inside that function use setstate to set selectCurrency = null; & selectExpense = null;. This will make the dropdownbutton show the hint instead of old record

flutter Textfiled makes unwanted rebuild

I have a ListBuilder inside MultiPageForm which creates a Card with 2 Textfields on each "add" tap. It used to work just fine but now it isn't - On each press, on the TextField the page is rebuilt, and the keyboard closes as soon as it opens.
List<AddIngredientItem> basic_ingredients = [];
This is the ListBuilder
ListView.builder(
physics: NeverScrollableScrollPhysics(),
shrinkWrap: true,
itemCount: basic_ingredients.length,
itemBuilder: (BuildContext context, index) {
return Dismissible(
background: slideBackground("right"),
secondaryBackground: slideBackground("left"),
key: UniqueKey(),
onDismissed: (direction) {
setState(
() {
basic_ingredients.removeAt(index);
},
);
},
child: basic_ingredients[index]);
},
),
This is the class which creates the Card with 2 TextFields:
import 'package:flutter/material.dart';
class AddIngredientItem extends StatefulWidget {
final _ingi_name_controller = TextEditingController();
final _ingi_amount_controller = TextEditingController();
final _measurement_controller = TextEditingController();
AddIngredientItem();
#override
String toStringShort() {
return _ingi_name_controller.text;
}
#override
_AddIngredientItemState createState() => _AddIngredientItemState();
}
class _AddIngredientItemState extends State<AddIngredientItem> {
List _measurements = ["1", "2", "3", "4", "5"];
List<DropdownMenuItem<String>> _dropDownMenuItems;
List<DropdownMenuItem<String>> getDropDownMenuItems() {
List<DropdownMenuItem<String>> items = new List();
for (String city in _measurements) {
items.add(new DropdownMenuItem(value: city, child: new Text(city)));
}
return items;
}
#override
void initState() {
_dropDownMenuItems = getDropDownMenuItems();
super.initState();
}
#override
Widget build(BuildContext context) {
return Card(
child: Padding(
padding: const EdgeInsets.all(5.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Expanded(
child: TextFormField(
controller: widget._ingi_name_controller,
maxLines: 1,
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 18.0,
),
onChanged: (val) {
setState(() {});
},
decoration: InputDecoration(
border: UnderlineInputBorder(
borderSide:
BorderSide(color: Theme.of(context).primaryColor),
),
hintText: 'hint',
),
),
),
Flexible(
child: TextFormField(
controller: widget._ingi_amount_controller,
keyboardType: TextInputType.number,
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 18.0,
),
maxLines: 1,
onChanged: (val) {
setState(() {});
},
decoration: InputDecoration(
border: UnderlineInputBorder(
borderSide:
BorderSide(color: Theme.of(context).primaryColor),
),
hintText: 'amount',
),
),
),
Flexible(
child: DropdownButton(
hint: Center(
child: Text("unit", style: TextStyle(fontSize: 18))),
value: widget._measurement_controller.text == ""
? null
: widget._measurement_controller.text,
items: _dropDownMenuItems,
onChanged: (val) {
widget._measurement_controller.text = val;
setState(() {});
},
)),
],
),
),
);
}
}
The issue is only about the TextField, any suggestions on how to make it work?
The problem was in the Unique.
Changing it to ValueKey helped.

Update data in database Firestore through TextFormField - Flutter

How to make the data that is written in the TextFormField update the data that has already been recorded
here is my login screen. This is part of the registration page. the same code on the login page
String _email, _password, id;
final GlobalKey<FormState> _formKey = GlobalKey<FormState>();
final db = Firestore.instance;
Expanded(
child: TextFormField(
autofocus: false,
// controller: _email,
// validator: Validator.validateEmail,
onSaved: (input) => _email = input,
decoration: InputDecoration(
border: InputBorder.none,
hintText: 'Enter your email',
hintStyle: TextStyle(color: Colors.grey),
),
),
),
Expanded(
child: FlatButton(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(30.0),
),
color: Colors.blue,
onPressed: () {},
child: Row(
children: <Widget>[
Padding(
padding: EdgeInsets.only(left: 20.0),
child: Text(
'SIGN UP',
style: TextStyle(color: Colors.white),
),
),
Expanded(
child: Container(),
),
Transform.translate(
offset: Offset(10.0, 0.0),
child: Container(
padding: EdgeInsets.all(1.0),
child: FlatButton(
shape: RoundedRectangleBorder(
borderRadius:
BorderRadius.circular(28.0)
),
color: Colors.white,
child: Icon(
Icons.arrow_forward,
color: Colors.blue,
),
onPressed: () async {
// _emailSignUp(
// email:_email.text,
// password:_password.text,
// context: context
// );
createData();
signUp();
sharedPreferences = await
SharedPreferences.getInstance();
sharedPreferences.setString("email", _email);
},
),
),
)
],
),
),
)
void createData() async {
if (_formKey.currentState.validate()) {
_formKey.currentState.save();
DocumentReference ref = await db.collection('users').add({'email': '$_email', 'name': 'UserName', 'userPhotoURL': 'url'});
setState(() => id = ref.documentID);
print(ref.documentID);
}
}
AccountScreen.
Here I want to update the data users through TextFormField. I want to determine what data needs to be changed depending on the user who came in
class AccountScreen extends StatefulWidget {
#override
State<StatefulWidget> createState() => AccountScreenState();
}
class AccountScreenState extends State<AccountScreen> {
final GlobalKey<FormState> _formKey = GlobalKey<FormState>();
String countries;
String selected;
SharedPreferences sharedPreferences;
String _name, _email;
final db = Firestore.instance;
#override
void initState() {
super.initState();
getDataPreference();
}
getDataPreference() async {
sharedPreferences = await SharedPreferences.getInstance();
setState(() {
_email = sharedPreferences.getString("email");
});
}
// void updateData(DocumentSnapshot doc) async {
// await db.collection('users').document(doc.documentID).updateData({'email': '$_email', 'name': '$_name'});
// Navigator.of(context).pushReplacementNamed('/home_screen');
// }
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Your account"), backgroundColor: Colors.blueGrey[900]),
body:
Container(
color: Colors.blueGrey[800],
child: Form(
key:_formKey,
child: ListView(
children: <Widget>[
AccountImage(),
ListTile(
leading: Icon(Icons.account_box, color: Colors.white),
title: TextFormField(
onSaved: (input) => _name = input,
style: TextStyle(color: Colors.white),
decoration: InputDecoration(
fillColor: Colors.white,
hintText: "Name",
hintStyle: TextStyle(color: Colors.white)),
)),
ListTile(
leading: Icon(Icons.email, color: Colors.white),
title: TextFormField(
style: TextStyle(color: Colors.white),
decoration: InputDecoration(
fillColor: Colors.white,
hintText: "Email",
hintStyle: TextStyle(color: Colors.white)),
// keyboardType: TextInputType.emailAddress,
initialValue: _email,
onSaved: (input) => _email = input,
),
),
ListTile(
leading: Icon(Icons.language, color: Colors.white),
title: DropDownCountries(),
),
Container(
padding: EdgeInsets.all(15.0),
child: Material(
color: Colors.blue[700],
elevation: 3.0,
child: MaterialButton(
height: 45.0,
child: Text("Save", style: TextStyle(color: Colors.white)),
onPressed: () {
// updateData();
Navigator.of(context).pushReplacementNamed('/home_screen');
}
),
),
)
],
),
)
),
);
}
}
You can update the record like this you can get documentID from document
Firestore.instance
.collection('users')
.document(userID)// use documentID here to update particular document
.updateData({
"email": emailController.text,//This is the data i.e going to be updated
"City": cityController.text,//This is the data i.e going to be updated
"Phone": phoneNumberController.text.toString(),//This is the data i.e going to be updated
});