Drop down inside text field flutter - flutter

This is what I have currently:
My design / what I want it to be:
This is my code and this sized box is a part of a column which is a part of a form:
SizedBox(
height: 80.0,
child: Stack(alignment: Alignment.centerRight, children: [
TextFormField(
controller: null,
style: const TextStyle(color: Colors.white),
maxLength: 2,
decoration: InputDecoration(
fillColor: const Color(0xff353251),
filled: true,
hintText: 'ex. 5 hours',
contentPadding: const EdgeInsets.all(20.0),
hintStyle: const TextStyle(color: Colors.white24),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(15.0)))),
DropdownButton(
value: goalValue,
dropdownColor: const Color(0xff403A4F),
style: const TextStyle(color: Colors.white),
onChanged: (String? value) {
setState(() {
goalValue = value!;
});
},
items: <String>['Per Week', 'Per Day', 'Per Month']
.map<DropdownMenuItem<String>>((String value) {
return DropdownMenuItem<String>(
value: value,
child: Text(value),
);
}).toList()),
]),
),
Thanks in advance!

Instead of Stack, I am using Container for outer decoration and Row for placing two widgets. There are many changes occur during styling the property and used random color, play with styling.
Now The result is
Container(
alignment: Alignment.center,
padding: const EdgeInsets.only(left: 16),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(15.0),
color: Color(0xff353251),
),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
const Flexible(
flex: 2,
child: TextField(
controller: null,
style: TextStyle(color: Colors.white),
maxLength: 2,
buildCounter: null,
decoration: InputDecoration(
fillColor: Color(0xff353251),
filled: true,
counterText: "",
hintText: 'ex. 5 hours',
contentPadding: EdgeInsets.only(right: 4),
hintStyle: TextStyle(color: Colors.white24),
border: InputBorder.none,
focusedBorder: InputBorder.none,
enabledBorder: InputBorder.none,
errorBorder: InputBorder.none,
),
),
),
Flexible(
flex: 1,
child: Container(
padding: EdgeInsets.only(right: 16, left: 16),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(15.0),
color: Colors.purpleAccent,
),
child: Theme(
data: Theme.of(context).copyWith(
canvasColor: Colors.purpleAccent,
),
child: DropdownButton(
borderRadius: BorderRadius.circular(15.0),
underline: const SizedBox(),
icon: const SizedBox(),
value: goalValue,
style: const TextStyle(color: Colors.white),
hint: const Text(
"select",
style: TextStyle(color: Colors.white),
),
onChanged: (String? value) {
setState(() {
goalValue = value!;
});
},
items: <String>['Per Week', 'Per Day', 'Per Month']
.map<DropdownMenuItem<String>>((String value) {
return DropdownMenuItem<String>(
value: value,
child: Text(value),
);
}).toList()),
),
),
),
],
),
),

Related

Flutter - how to vertically align text input within a container?

I am trying to add a search input control to the app header in my Flutter web app.
See...
Widget _buildSearchControl() {
return Container(
alignment: Alignment.centerLeft,
color: Colors.white,
padding: EdgeInsets.only(right: 20),
margin: EdgeInsets.all(10),
width: 300,
child: TextField(
style: TextStyle(backgroundColor: Colors.white, color: Colors.black),
decoration: InputDecoration(
prefixIcon: const Icon(Icons.search,color: Colors.black,),
suffixIcon: IconButton(
icon: const Icon(Icons.clear,color: Colors.black,),
onPressed: () {
/* Clear the search field */
},
),
hintText: 'Search...',
border: InputBorder.none),
),
);
}
However, when entering the text, the characters are not vertically centre aligned as I wpuld expect
Is there a way I can have the characters input to the TextField control vertically centered so that they line up with the icons?
Have you tried this textAlignVertical property?
TextField(
textAlignVertical: TextAlignVertical.center,
....
),
I wrap the Container with Padding.
And add contentPadding: const EdgeInsets.all(5), to InputDecoration
...
Padding(
padding: const EdgeInsets.all(8.0).copyWith(bottom: 0),
child: Container(
decoration: BoxDecoration(
border: Border.all(color: Theme.of(context).primaryColor, width: 2),
borderRadius: const BorderRadius.all(Radius.circular(10)),
color: Colors.white
),
child: TextFormField(
controller: _controller,
onChanged: (string) {},
style: TextStyle(color: Theme.of(context).primaryColor),
cursorColor: Theme.of(context).primaryColor,
decoration: InputDecoration(
contentPadding: const EdgeInsets.all(5),
enabledBorder: InputBorder.none,
focusedBorder: InputBorder.none,
labelText: 'Enter',
labelStyle: TextStyle(
color: Theme.of(context).primaryColor,
fontSize: 16,
fontWeight: FontWeight.w500),
prefixIcon: Icon(
Icons.document_scanner_sharp,
color: Theme.of(context).primaryColor,
),
suffixIcon: Padding(
padding: const EdgeInsets.only(top: 5.0),
child: IconButton(
alignment: Alignment.topLeft,
icon: const Icon(
Icons.clear,
size: 25,
color: Colors.red,
),
tooltip: 'Clear',
onPressed: () {
FocusScope.of(context).unfocus();
_controller.clear();
}
),
)
)
),
),
),
Use this , maybe it depends on your contentPadding
Container(
width: 300,
height: 56,
margin: EdgeInsets.fromLTRB(0, 0, 0, 20),
child: TextFormField(
key: widget.globalKey,
autocorrect: false,
onTap: widget.onClick,
minLines: widget.minLines,
maxLines: widget.maxLines,
textInputAction: TextInputAction.done,
onChanged: (val) => widget.onChangeValue(val),
style: getInputStyle,
initialValue: widget.initialValue,
textAlign: TextAlign.left,
autovalidateMode: AutovalidateMode.onUserInteraction,
controller: widget.controller,
keyboardAppearance: Brightness.dark,
decoration: InputDecoration(
contentPadding: REdgeInsets.fromLTRB(
14, 16, 0, 16),
labelText: widget.labelText,
hintText: widget.hintText,
floatingLabelBehavior: FloatingLabelBehavior.auto,
labelStyle: getLabelStyle,
hintStyle: getLabelStyle,
fillColor: widget.backGroundColor ,
filled: true,
prefix: widget.prefix,
),
),
)

How can I save appointment information in real-time database using flutter and attach the uid? [duplicate]

I am working on saving car details of the user on real-time firebase but having difficulties. Any assistance is highly appreciated. Below is the sample of the code that I am working on. It has two dropdown buttons that are depended on each other and store vital information on the car model and make of the user.
return Scaffold(
appBar: AppBar(
title: const Text('Car Type'),
centerTitle: true,
),
body: SingleChildScrollView(
key: _formKeyValue,
// autovalidateMode: AutovalidateMode.always,
child: Column(
children: <Widget>[
const SizedBox(
height: 10,
),
DropdownButton<String?>(
value: selectedCarModel,
items: dataset.keys.map((e) {
return DropdownMenuItem<String?>(
value: e,
child: Text(e),
);
}).toList(),
onChanged: onCarModelChanged,
hint: const Text('car model'),
),
const SizedBox(
height: 10,
),
DropdownButton<String?>(
value: selectedCarMake,
hint: const Text('car make'),
items: (dataset[selectedCarModel] ?? []).map((e) {
return DropdownMenuItem<String?>(
value: e,
child: Text(e),
);
}).toList(),
onChanged: (val) {
setState(() {
selectedCarMake = val!;
});
}),
const SizedBox(
height: 10,
),
// year textfield
Padding(
padding: const EdgeInsets.all(8.0),
child: TextFormField(
controller: _yearController,
enableSuggestions: false,
keyboardType: TextInputType.number,
decoration: InputDecoration(
hintText: 'Year',
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(10),
borderSide: const BorderSide(color: Colors.orange),
),
),
),
),
//space in between the two fields
const SizedBox(
height: 10,
),
//applied model textfield
Padding(
padding: const EdgeInsets.all(8.0),
child: TextFormField(
controller: _appModelController,
enableSuggestions: false,
keyboardType: TextInputType.name,
decoration: InputDecoration(
hintText: 'Applied Model',
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(10),
borderSide: const BorderSide(color: Colors.deepOrange),
),
),
),
),
const SizedBox(
height: 10,
),
//numberplate textfield
Padding(
padding: const EdgeInsets.all(8.0),
child: TextFormField(
controller: _numberPlateController,
enableSuggestions: false,
decoration: InputDecoration(
hintText: 'Number Plate',
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(10),
borderSide: const BorderSide(color: Colors.deepOrange),
),
),
),
),
const SizedBox(
height: 10,
),
//add car textbutton
ElevatedButton(
onPressed: () {
if (_yearController.text.isNotEmpty &&
_appModelController.text.isNotEmpty &&
_numberPlateController.text.isNotEmpty) {
insertData(
_yearController.text,
_appModelController.text,
_numberPlateController.text,
);
}
},
child: const Text('ADD CAR'),
),

How can I save user information using uid in real-time database using flutter?

I am working on saving car details of the user on real-time firebase but having difficulties. Any assistance is highly appreciated. Below is the sample of the code that I am working on. It has two dropdown buttons that are depended on each other and store vital information on the car model and make of the user.
return Scaffold(
appBar: AppBar(
title: const Text('Car Type'),
centerTitle: true,
),
body: SingleChildScrollView(
key: _formKeyValue,
// autovalidateMode: AutovalidateMode.always,
child: Column(
children: <Widget>[
const SizedBox(
height: 10,
),
DropdownButton<String?>(
value: selectedCarModel,
items: dataset.keys.map((e) {
return DropdownMenuItem<String?>(
value: e,
child: Text(e),
);
}).toList(),
onChanged: onCarModelChanged,
hint: const Text('car model'),
),
const SizedBox(
height: 10,
),
DropdownButton<String?>(
value: selectedCarMake,
hint: const Text('car make'),
items: (dataset[selectedCarModel] ?? []).map((e) {
return DropdownMenuItem<String?>(
value: e,
child: Text(e),
);
}).toList(),
onChanged: (val) {
setState(() {
selectedCarMake = val!;
});
}),
const SizedBox(
height: 10,
),
// year textfield
Padding(
padding: const EdgeInsets.all(8.0),
child: TextFormField(
controller: _yearController,
enableSuggestions: false,
keyboardType: TextInputType.number,
decoration: InputDecoration(
hintText: 'Year',
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(10),
borderSide: const BorderSide(color: Colors.orange),
),
),
),
),
//space in between the two fields
const SizedBox(
height: 10,
),
//applied model textfield
Padding(
padding: const EdgeInsets.all(8.0),
child: TextFormField(
controller: _appModelController,
enableSuggestions: false,
keyboardType: TextInputType.name,
decoration: InputDecoration(
hintText: 'Applied Model',
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(10),
borderSide: const BorderSide(color: Colors.deepOrange),
),
),
),
),
const SizedBox(
height: 10,
),
//numberplate textfield
Padding(
padding: const EdgeInsets.all(8.0),
child: TextFormField(
controller: _numberPlateController,
enableSuggestions: false,
decoration: InputDecoration(
hintText: 'Number Plate',
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(10),
borderSide: const BorderSide(color: Colors.deepOrange),
),
),
),
),
const SizedBox(
height: 10,
),
//add car textbutton
ElevatedButton(
onPressed: () {
if (_yearController.text.isNotEmpty &&
_appModelController.text.isNotEmpty &&
_numberPlateController.text.isNotEmpty) {
insertData(
_yearController.text,
_appModelController.text,
_numberPlateController.text,
);
}
},
child: const Text('ADD CAR'),
),

How to reduce the height of the DropDownButtonFormField so that the text inside it does not go out of the middle in flutter?

When I set a height for my container that is the parent of DropDownButtonFormField, I have no problem when the height is 55, but when the height is less (42) than a certain limit, the text inside it looks like this.
As it is clear in the picture, cat is no longer in the middle of the container.
this is my code:
Container(
alignment: Alignment.center,
width: double.infinity,
height: 40,
decoration: BoxDecoration(
color: Colors.white,
border: Border.all(
color: const Color(0xFF616161),
width: 0.65,
),
borderRadius: BorderRadius.circular(8),
),
child: Padding(
padding: EdgeInsets.fromLTRB(0, 0, 10, 0),
child: DropdownButtonFormField(
enableFeedback: true,
menuMaxHeight: 200,
icon: Icon(Icons.keyboard_arrow_down_rounded),
iconSize: 21,
alignment: Alignment.center,
// decoration: InputDecoration.collapsed(hintText: ''),
decoration: InputDecoration(
border: InputBorder.none,
prefixIcon: Icon(Icons.location_on_rounded),
),
dropdownColor: Colors.white,
borderRadius: BorderRadius.all(Radius.circular(8)),
elevation: 2,
// isExpanded: true,
value: cityValue,
onChanged: (String? newValue) {
setState(() {
cityValue = newValue!;
});
},
items: <String>['Tehran', 'Cat', 'Tiger', 'Lion']
.map<DropdownMenuItem<String>>((String value) {
return DropdownMenuItem<String>(
value: value,
child: Text(
value,
style:
TextStyle(fontSize: 15, color: Color(0xff707070)),
),
);
}).toList(),
),
),
),
The icon is in the middle but not the text.
I used Offset, but then the icon gets messed up.
The default Icon size 24, so you need minimum height 48 to view properly. It would be better not to force it have certain height.You can remove height 40 for better UX.
Now let say you like to have fixed hight, for this case, you need to maintain padding for yourself.
decoration: InputDecoration(
border: InputBorder.none,
contentPadding: EdgeInsets.only(top: 6), //this one
prefixIcon: Icon(Icons.location_on_rounded),
),
Container(
alignment: Alignment.center,
width: double.infinity,
height: 40,
decoration: BoxDecoration(
color: Colors.white,
border: Border.all(
color: const Color(0xFF616161),
width: 0.65,
),
borderRadius: BorderRadius.circular(8),
),
child: Padding(
padding: EdgeInsets.fromLTRB(0, 0, 0, 0),
child: DropdownButtonFormField(
enableFeedback: true,
menuMaxHeight: 200,
icon: Icon(Icons.keyboard_arrow_down_rounded),
iconSize: 20,
alignment: Alignment.center,
// decoration: InputDecoration.collapsed(hintText: ''),
decoration: InputDecoration(
border: InputBorder.none,
contentPadding: EdgeInsets.only(top: 6), //this one
prefixIcon: Icon(Icons.location_on_rounded),
),
dropdownColor: Colors.white,
borderRadius: BorderRadius.all(Radius.circular(8)),
elevation: 2,
onChanged: (String? newValue) {},
items: <String>['Tehran', 'Cat', 'Tiger', 'Lion']
.map<DropdownMenuItem<String>>((String value) {
return DropdownMenuItem<String>(
value: value,
child: Text(
value,
style:
TextStyle(fontSize: 15, color: Color(0xff707070)),
),
);
}).toList(),
),
),
),
A quick solution is adding a contentPadding to the InputDecoration.
contentPadding: EdgeInsets.symmetric(vertical: 7),
Try below code using InputDecoration
DropdownButtonFormField(
decoration: const InputDecoration(
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.all(Radius.circular(4)),
borderSide: BorderSide(width: 1, color: Colors.grey),
),
contentPadding: EdgeInsets.symmetric(
horizontal: 10.0,
vertical: 3.0,
),
border: OutlineInputBorder(),
prefixIcon: Icon(
Icons.location_on_rounded,
color: Colors.grey,
),
),
dropdownColor: Colors.white,
borderRadius: const BorderRadius.all(
Radius.circular(8),
),
icon: const Icon(Icons.keyboard_arrow_down_rounded),
onChanged: (value) => {
cityValue = value!,
},
items: <String>['Tehran', 'Cat', 'Tiger', 'Lion']
.map(
(e) => DropdownMenuItem(
value: e,
child: Text(e),
),
)
.toList(),
),
Your Result Screen->

A RenderFlex overflowed by 147 pixels on the bottom

Here is the screenshot of the app I am trying to build.
The Date of birth field should show a calendar on click of it. Suppose I am in the email textformfield and the keyboard is open and now the user moves to date of birth field. As soon as user taps on date of birth field, I am removing the keyboard and showing the calendar, at that time I am getting exception saying A RenderFlex overflowed by 147 pixels on the bottom.
I have already gone through a bunch of stack questions on this and it mentioned to use a ListView, which I am using. Here is a snippet of my code.
return Scaffold(
body: Column(
children: <Widget>[
Expanded(
child: Padding(
padding: const EdgeInsets.fromLTRB(20.0, 8.0, 40.0, 8.0),
child: InkWell(
onTap: () {
FocusScope.of(context).requestFocus(FocusNode());
},
child: ListView(
children: <Widget>[
Image.asset(
"images/alphaurbanelogo.png",
width: 150.0,
height: 150.0,
),
Text("Sign Up",
style: TextStyle(
color: Colors.black,
fontFamily: "aktivgroteskBold",
fontSize: 25.0)),
SizedBox(
height: 5.0,
),
Text("Create an account to access\n TAUP system",
style: TextStyle(
color: Colors.black,
fontFamily: "aktivgroteskLight",
fontSize: 15.0)),
SizedBox(
height: 10.0,
),
TextFormField(
style: TextStyle(color: Color(0xFF5c2a7c)),
decoration: InputDecoration(
hintText: "First Name",
hintStyle: TextStyle(color: Color(0xFF5c2a7c)),
focusedBorder: UnderlineInputBorder(
borderSide: BorderSide(color: Color(0xFF5c2a7c)))),
),
SizedBox(
height: 10.0,
),
TextFormField(
style: TextStyle(color: Color(0xFF5c2a7c)),
decoration: InputDecoration(
hintText: "Last Name",
hintStyle: TextStyle(color: Color(0xFF5c2a7c)),
focusedBorder: UnderlineInputBorder(
borderSide: BorderSide(color: Color(0xFF5c2a7c)))),
),
SizedBox(
height: 10.0,
),
TextFormField(
style: TextStyle(color: Color(0xFF5c2a7c)),
decoration: InputDecoration(
hintText: "Email",
hintStyle: TextStyle(color: Color(0xFF5c2a7c)),
focusedBorder: UnderlineInputBorder(
borderSide: BorderSide(color: Color(0xFF5c2a7c)))),
),
SizedBox(
height: 10.0,
),
InkWell(
onTap: () {
FocusScope.of(context).requestFocus(FocusNode());
_selectDate(context);
},
child: Row(
children: <Widget>[
Flexible(
child: TextFormField(
style: TextStyle(
color: Color(0xFF5c2a7c), height: 2.0),
enabled: false,
controller: dobController,
decoration: InputDecoration.collapsed(
hintText: "Date of Birth",
hintStyle: TextStyle(color: Color(0xFF5c2a7c)),
)),
),
Icon(
Icons.email,
color: Color(0xFF5c2a7c),
),
],
),
),
Divider(
color: Color(0xFF5c2a7c),
height: 5.0,
),
SizedBox(
height: 10.0,
),
TextFormField(
style: TextStyle(color: Color(0xFF5c2a7c)),
keyboardType: TextInputType.number,
decoration: InputDecoration(
hintText: "Contact Number",
hintStyle: TextStyle(color: Color(0xFF5c2a7c)),
focusedBorder: UnderlineInputBorder(
borderSide: BorderSide(color: Color(0xFF5c2a7c)))),
),
SizedBox(
height: 10.0,
),
TextFormField(
style: TextStyle(color: Color(0xFF5c2a7c)),
decoration: InputDecoration(
hintText: "Parent Email",
hintStyle: TextStyle(color: Color(0xFF5c2a7c)),
focusedBorder: UnderlineInputBorder(
borderSide: BorderSide(color: Color(0xFF5c2a7c)))),
),
SizedBox(
height: 10.0,
),
TextFormField(
style: TextStyle(color: Color(0xFF5c2a7c)),
keyboardType: TextInputType.number,
decoration: InputDecoration(
hintText: "Parent Contact Number",
hintStyle: TextStyle(color: Color(0xFF5c2a7c)),
focusedBorder: UnderlineInputBorder(
borderSide: BorderSide(color: Color(0xFF5c2a7c)))),
),
SizedBox(
height: 10.0,
),
DropdownButton<String>(
items: _schools.map((String dropDownStringItem) {
return DropdownMenuItem<String>(
value: dropDownStringItem,
child: Text(dropDownStringItem),
);
}).toList(),
hint: Text("School/Institution"),
onChanged: (String newValueSelected) {
setState(() {
this._currentItemSelected = newValueSelected;
});
},
value: _currentItemSelected,
style: TextStyle(color: Color(0xFF5c2a7c), fontSize: 16.0),
),
SizedBox(
height: 1.0,
),
Divider(
color: Color(0xFF5c2a7c),
height: 5.0,
),
SizedBox(
height: 10.0,
),
Row(
children: <Widget>[
Spacer(),
InkWell(
child: Image.asset(
"images/next.png",
width: 40.0,
height: 40.0,
),
onTap: () {},
)
],
)
],
),
),
)),
BottomBar()
],
),
);
Future<Null> _selectDate(BuildContext context) async {
final DateTime picked = await showDatePicker(
context: context,
initialDate: DateTime.now(),
firstDate: new DateTime(1900),
lastDate: new DateTime(2100));
if (picked != null) {
var formatter = new DateFormat('yyyy-MM-dd');
choosenDate = formatter.format(picked);
dobController.text = choosenDate;
}
}
I am using a Form widget and its bottom was overflown, so similar problem. My solution was to apply a SingleChildScrollView widget. It was very convenient, as I was using a padding widget and this one has a padding property too. Just replaced it and perfect.
return Form(
key: _formKey,
autovalidate: _autoValidate,
child: SingleChildScrollView(
padding: const EdgeInsets.all(10.0),
child: Column(
(...)
Source
If you're using a scaffold, type ResizetToAvoidBottomPadding: false.