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
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,
),
),
)
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'),
),
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'),
),
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->
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.