I have started learning Flutter recently and wanted to know how to write code that displays multiple text field of same sized box, text style, decoration. I have written code where i use Text Field for every new input is required instead want to code a dummy and call it where i want the text field and change the hint text. Let say i want to use these structure in all my text field, but don't want to write the whole code once again with different hintText
SizedBox(height: 20),
Container(
//Type TextField
width: width * 0.8,
height: height * 0.053,
color: fcolor,
child: TextField(
decoration: InputDecoration(
contentPadding: EdgeInsets.all(10.0),
enabledBorder: UnderlineInputBorder(
borderSide: BorderSide(color: Colors.white),
),
hintText: 'Type',
hintStyle: TextStyle(color: tcolor),
),
style: TextStyle(color: icolor),
),
),
You can create a Widget and pass the hintText and other properties you would like to(as parameters) like below:
Widget _buildTextField({String hintText, // add other properties here}) { // new
return Container(
//Type TextField
width: width * 0.8,
height: height * 0.053,
color: fcolor,
child: TextField(
decoration: InputDecoration(
contentPadding: EdgeInsets.all(10.0),
enabledBorder: UnderlineInputBorder(
borderSide: BorderSide(color: Colors.white),
),
hintText: hintText, // pass the hint text parameter here
hintStyle: TextStyle(color: tcolor),
),
style: TextStyle(color: icolor),
),
);
}
Then use the _buildTextField method in your StatelessWidget or StatefulWidget like below:
class StackOver extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
body: Column(
children: [
_buildTextField(hintText: 'First Name'),
SizedBox(height: 20,),
_buildTextField(hintText: 'Last Name'),
],
),
);
}
}
Do it like this,
Create a function which returns a widget (..textfield)
Widget getTextField(String hintText){
return Container(
//Type TextField
width: width * 0.8,
height: height * 0.053,
color: fcolor,
child: TextField(
decoration: InputDecoration(
contentPadding: EdgeInsets.all(10.0),
enabledBorder: UnderlineInputBorder(
borderSide: BorderSide(color: Colors.white),
),
hintText: hintText,
hintStyle: TextStyle(color: tcolor),
),
style: TextStyle(color: icolor),
);
Now, wherever you need textfield, call this method and pass your hintText,
Example,
getTextField("this is hint text");
Declare common textfield widget like this
class CsCommonTextFieldWidget extends StatefulWidget {
const CsCommonTextFieldWidget(
{this.titleText = '',
this.titleTextAlign = TextAlign.center,
required this.isPassword,
required this.hintText,
required this.textController});
final String titleText;
final TextAlign titleTextAlign;
final bool isPassword;
final String hintText;
final TextEditingController textController;
#override
_CsCommonTextFieldWidgetState createState() =>
_CsCommonTextFieldWidgetState();
}
class _CsCommonTextFieldWidgetState extends State<CsCommonTextFieldWidget> {
#override
Widget build(BuildContext context) {
return TextField(
obscureText: widget.isPassword,
decoration: InputDecoration(
contentPadding: EdgeInsets.all(10.0),
hintText: widget.hintText, // pass the hint text parameter here
hintStyle: TextStyle(color: Colors.black26),
),
style: TextStyle(color: Colors.black),
);
}
}
Usage
Container(
width: double.infinity,
margin: const EdgeInsets.fromLTRB(0, CsDimens.SPACE40, 0, 0),
child: CsCommonTextFieldWidget(
isPassword: false,
hintText: Languages.of(context)!.labelEmail,
textController: emailController,
),
),
Related
I have created a customTextfield and placed IconButton as suffix icon,
here when I tap on icon button, its splash radius showing bigger than textfield,
here I want to fix height of splash radius based on it's parent.. like if it is inside of container of 100height..it must be set according to it...
here is my code
class CustomTextField extends StatelessWidget {
final String hint;
final bool isitpassword;
final TextEditingController controller;
const CustomTextField({Key? key,required this.hint,this.isitpassword=false,required this.controller}) : super(key: key);
#override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.symmetric(horizontal: 10.0),
child: Container(
padding: EdgeInsets.symmetric(horizontal: 20),
decoration: BoxDecoration(
color: Colors.grey,
borderRadius: BorderRadius.circular(20),
),
child: TextField(
style: TextStyle(
fontSize: 20,color: Colors.white,),
controller: controller,
obscureText: isitpassword,
decoration: InputDecoration(
border: InputBorder.none,
hintText: hint,
suffixIcon: IconButton(
//what spread radius to set for better view
icon: Icon(Icons.close,color: Colors.white,),onPressed: (){
controller.text='';
},),
),
)),
);
}
}
You can use splashRadius: 48 / 2
you can use InkWell instead like this it will take size as much as its parent:
TextField(
style: TextStyle(
fontSize: 20,
color: Colors.white,
),
controller: controller,
obscureText: isitpassword,
decoration: InputDecoration(
border: InputBorder.none,
hintText: hint,
suffixIcon: InkWell(
borderRadius: BorderRadius.circular(100),
child: Icon(
Icons.close,
color: Colors.white,
),
onTap: () {
controller.text = '';
},
)),
),
the 100 number is not important just set a big number.
I need to align hint text and leading icon in the center, like shown here:
When I add a leading icon, and centre align decoration that is what I get. I need the icon to be in the centre as well.
Edit: Current code
TextField(
textAlign: TextAlign.center,
decoration: InputDecoration(
hintText: 'Type something',
prefixIcon: Icon(Icons.search)
)
),
There is a widget for your case: IntrinsicWidth. This widget is used to size its child to the child's intrinsic width.
Output
Full code:
class CenteredTextField extends StatefulWidget {
const CenteredTextField({Key key}) : super(key: key);
#override
_CenteredTextFieldState createState() => _CenteredTextFieldState();
}
class _CenteredTextFieldState extends State<CenteredTextField> {
#override
Widget build(BuildContext context) {
return Scaffold(
body: Container(
height: 40.0,
margin: EdgeInsets.symmetric(horizontal: 20.0, vertical: 50.0),
decoration: BoxDecoration(
color: Colors.orange.withOpacity(0.4),
borderRadius: BorderRadius.circular(20.0),
border: Border.all(
color: Colors.orange,
width: 1.0,
),
),
child: Center(
child: IntrinsicWidth(
child: TextField(
textAlignVertical: TextAlignVertical.center,
decoration: InputDecoration(
prefixIcon: Icon(Icons.search),
hintText: 'Type verse address',
border: InputBorder.none,
),
),
),
),
),
);
}
}
how to create a textfield with centered hint text and suffix icon?
i make centered hint with TextAlign.center
the problem is that when i add an suffix icon hint does not stay in center and moves to left
Well, this is working fine for me.
If it doesn't work, maybe is something else affecting your UI.
Please try this snippet.
TextField(
textAlign: TextAlign.center,
decoration: InputDecoration(
hintText: 'Center the text',
suffixIcon: IconButton(
icon: Icon(Icons.add),
onPressed: () {
debugPrint('click bait');
}
),
),
),
Try with a below code snippet that has prefix and sufixicon in a textformField
Create a Textfield widget like a below:
import 'package:flutter/material.dart';
import 'package:row_nation/Utils/app_colors.dart';
import 'package:row_nation/Utils/app_font_size.dart';
import 'package:row_nation/Utils/app_font_weight.dart';
class PassWordTextFormFieldWidget extends StatelessWidget {
final TextEditingController controllerName;
final String hintTxt;
final TextInputType keyboardType;
final Color cursorColor;
final Function(String) onChange;
final Function(String) onSaved;
final String? Function(String?)? validatorData;
final IconData prefixIcon;
final IconData suffixIcon;
final Function() sufficIconTap;
PassWordTextFormFieldWidget({
super.key,
required this.controllerName,
required this.hintTxt,
required this.prefixIcon,
required this.keyboardType,
required this.cursorColor,
required this.onChange,
required this.onSaved,
required this.validatorData,
required this.suffixIcon,
required this.sufficIconTap,
});
#override
Widget build(BuildContext context) {
double? height, width;
height = MediaQuery.of(context).size.height;
width = MediaQuery.of(context).size.width;
return Container(
height: 50,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(12),
color: AppColors.kEmptyDotColor.withOpacity(0.4),
),
child: TextFormField(
controller: controllerName,
cursorColor: cursorColor,
obscureText: true,
textAlign: TextAlign.left,
keyboardType: keyboardType,
style: Theme.of(context).textTheme.caption?.copyWith(
color: AppColors.kWhiteColor,
letterSpacing: 0.2,
fontSize: AppFontSize.fourteenFontSize,
fontWeight: AppFontWeight.sixHundredFont,
),
validator: (value) {
// widget.validatorData!(value);
return validatorData!(value);
},
onChanged: (va) {
onChange(va);
},
onSaved: (val) {
print(val);
},
decoration: InputDecoration(
contentPadding: EdgeInsets.symmetric(
horizontal: 15,
vertical: 15,
),
isDense: true,
hintText: hintTxt,
hintStyle: Theme.of(context).textTheme.caption?.copyWith(
color: AppColors.kIconColor,
fontSize: AppFontSize.twelveFontSize,
fontWeight: AppFontWeight.fourHundredFont,
),
// When user gets Error
errorBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(12),
borderSide: BorderSide(
color: AppColors.kRedColor,
),
),
// When user getting error and focuses on a textformfield
focusedErrorBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(12),
borderSide: BorderSide(
color: AppColors.kRedColor,
),
),
// When user Focuses on textformField widget
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(12),
borderSide: BorderSide(
color: AppColors.kSplashBackColor,
),
),
// Default TextformField Color
enabledBorder: InputBorder.none,
suffixIcon: GestureDetector(
onTap: () {
sufficIconTap();
},
child: Icon(
suffixIcon,
size: 15,
color: AppColors.kIconColor,
),
),
prefixIcon: Icon(
prefixIcon,
size: 15,
color: AppColors.kIconColor,
),
// border: InputBorder.none,
),
),
);
}
}
and use it wherever like a below :
PassWordTextFormFieldWidget(
controllerName: passwordController,
prefixIcon: Icons.lock,
suffixIcon: Icons.visibility_off,
sufficIconTap: () {
print("Visibility Icon Tapped");
},
hintTxt: AppStrings.passwordTxt,
keyboardType: TextInputType.text,
cursorColor: AppColors.kSplashBackColor,
onChange: (p0) {},
onSaved: (p0) {},
validatorData: (p0) {},
),
Don't forget to upvote if found useful.
Today I made a custom text field of my own and I want to use it in many of the pages but it contains some arguments.
You can see here
import 'package:flutter/material.dart';
class RequiredText extends StatefulWidget {
#override
_RequiredTextState createState() => _RequiredTextState();
}
class _RequiredTextState extends State<RequiredText> {
final myController = TextEditingController();
#override
void dispose() {
myController.dispose();
super.dispose();
}
#override
Widget build(BuildContext context) {
String LabelTextField;
String HelperTextField;
Color ColorBorder;
Color ColorField;
Color ColorCursor;
return Padding(
padding: const EdgeInsets.only(left: 18.0),
child: TextField(
cursorColor: ColorCursor,
style: TextStyle(
color: ColorField,
),
keyboardType: TextInputType.number,
textInputAction: TextInputAction.next,
controller: myController,
decoration: InputDecoration(
enabledBorder: new OutlineInputBorder(
borderSide: BorderSide(width: 1.5, color: ColorBorder)),
border: OutlineInputBorder(
borderSide: new BorderSide(color: Colors.cyan[200]),
borderRadius: new BorderRadius.all(Radius.circular(20.0))),
helperText: HelperTextField,
labelText: LabelTextField,
labelStyle: TextStyle(
color: Colors.black26,
fontSize: 20.0,
fontFamily: 'DancingScript',
),
icon: Icon(
Icons.apps,
)),
),
);
}
}
But I want to use this in my main.dart class and other pages too.
But it is showing errors
import 'package:AllInOneCalci/CustomTextFields.dart';
import 'package:AllInOneCalci/customAppBar.dart';
import 'package:flutter/material.dart';
class BMICalcUI extends StatefulWidget {
#override
_BMICalcUIState createState() => _BMICalcUIState();
}
class _BMICalcUIState extends State<BMICalcUI> {
#override
Widget build(BuildContext context) {
double AppBarHeight = MediaQuery.of(context).size.height;
return Scaffold(
appBar: customAppBar(
height: (AppBarHeight / 3) * 0.4,
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Padding(
padding: const EdgeInsets.only(top: 18.0),
child: Text(
'All In One Cali',
style: TextStyle(
color: Colors.black,
fontSize: 35.0,
fontFamily: 'DancingScript',
fontWeight: FontWeight.bold),
),
),
],
),
),
body: Padding(
padding: const EdgeInsets.only(top: 18.0),
child: Container(
width: 300.0,
child: Column(
children: [
RequiredText('Height', 'Input height in meters', Colors.cyan[200],
Colors.redAccent, Colors.redAccent),
],
),
),
),
);
}
}
Also I want to use this in many of my pages. Can you help me that how can I do this?
It would be very helpful to me. I am Stuck here
RequiredText('Height', 'Input height in meters', Colors.cyan[200],
Colors.redAccent, Colors.redAccent),
This line is showing error.
String LabelTextField;
String HelperTextField;
Color ColorBorder;
Color ColorField;
Color ColorCursor;
you mentioned the param but you didn't initialize it ,
do it in this way
class RequiredText extends StatefulWidget {
String LabelTextField;
String HelperTextField;
Color ColorBorder;
Color ColorField;
Color ColorCursor;
RequiredText(this.LabelTextField,this.HelperTextField,this.ColorBorder,this.ColorField,this.ColorCursor);
#override
_RequiredTextState createState() => _RequiredTextState();
}
class _RequiredTextState extends State<RequiredText> {
final myController = TextEditingController();
#override
void dispose() {
myController.dispose();
super.dispose();
}
#override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.only(left: 18.0),
child: TextField(
cursorColor: widget.ColorCursor,
style: TextStyle(
color: widget.ColorField,
),
keyboardType: TextInputType.number,
textInputAction: TextInputAction.next,
controller: myController,
decoration: InputDecoration(
enabledBorder: new OutlineInputBorder(
borderSide: BorderSide(width: 1.5, color: widget.ColorBorder)),
border: OutlineInputBorder(
borderSide: new BorderSide(color: Colors.cyan[200]),
borderRadius: new BorderRadius.all(Radius.circular(20.0))),
helperText: widget.HelperTextField,
labelText: widget.LabelTextField,
labelStyle: TextStyle(
color: Colors.black26,
fontSize: 20.0,
fontFamily: 'DancingScript',
),
icon: Icon(
Icons.apps,
)),
),
);
}
}
The Desired Effect is to have Kartennummer and Passwort centrated.
How is this possible?
I use a custom class for this:
import 'package:flutter/material.dart';
import 'package:impex_shop/styles/impex_styles.dart';
class ImpexTextField extends StatefulWidget {
final TextEditingController controller;
final bool obscureText;
final TextInputType keyboardType;
final String labelText;
final IconData prefixIcon;
final int maxLines;
final TextInputAction textInputAction;
final void Function(String) onSubmitted;
final bool autofocus;
const ImpexTextField(
{Key key,
this.controller,
this.obscureText,
this.keyboardType,
this.labelText,
this.prefixIcon,
this.maxLines = 1,
this.textInputAction,
this.onSubmitted,
this.autofocus = false})
: super(key: key);
#override
_ImpexTextFieldState createState() => _ImpexTextFieldState();
}
class _ImpexTextFieldState extends State<ImpexTextField> {
FocusNode _focusNode = FocusNode();
Paint paint;
InputDecoration buildTextInputDecoration(
String labelText, TextEditingController controller, IconData prefixIcon) {
return InputDecoration(
labelText: labelText,
labelStyle: TextStyle(
color: ImpexColors.mainColor,
height: 0.8, // 0,1 - label will sit on top of border
background: paint,
),
fillColor: ImpexColors.lightGrey,
filled: true,
enabledBorder: OutlineInputBorder(
borderSide: const BorderSide(
color: ImpexColors.grey,
width: 1.0,
),
),
focusedBorder: OutlineInputBorder(
borderSide: const BorderSide(
color: ImpexColors.secondaryColor,
width: 2.0,
),
),
suffixIcon: InkWell(
onTap: () => controller.clear(),
child: Icon(Icons.cancel),
),
prefixIcon: prefixIcon == null ? null : Icon(prefixIcon),
);
}
#override
Widget build(BuildContext context) {
return Container(
child: ListView(
shrinkWrap: true,
physics: ClampingScrollPhysics(),
children: <Widget>[
Container(
height: 12,
),
TextField(
textAlign: TextAlign.center,
textAlignVertical: TextAlignVertical.center,
focusNode: _focusNode,
controller: widget.controller,
obscureText: widget.obscureText ?? false,
maxLines: widget.maxLines,
textInputAction: widget.textInputAction,
decoration: buildTextInputDecoration(
widget.labelText, widget.controller, widget.prefixIcon),
keyboardType: widget.keyboardType,
autofocus: widget.autofocus,
onSubmitted: widget.onSubmitted,
onTap: () => setState(() {
FocusScope.of(context).requestFocus(_focusNode);
}),
),
],
),
);
}
#override
void dispose() {
_focusNode.dispose();
super.dispose();
}
}
A Very and Handy solution to Center the Label:
Since Label is accepting Widget after flutter 2.5.x, so you can wrap your Text widget into
Center widget like this,
TextFormField(
decoration: InputDecoration(
label: const Center(
child: Text("Your Centered Label Text"),
),
),
)
Note:
If Upper border is not Visible due to this, Then:
Try Wraping Center widget to Row, and give mainAxisSize: MainAxisSize.min, this will not cover the entire border
There is a nice decision for this.
Try to use alignLabelWithHint: true.
As example:
TextField(keyboardType: TextInputType.number, textAlign: TextAlign.center, maxLines: 1, decoration: InputDecoration(alignLabelWithHint: true, enabledBorder: InputBorder.none, contentPadding: EdgeInsets.zero, focusedBorder: InputBorder.none, border: InputBorder.none, labelStyle: Theme.of(context).textTheme.headline6, labelText: 'Amount (GPB)'.toUpperCase(),),),
I had a similar problem with labels, my solution was, as Ragu Swaminathan says, to create my own custom widget that used a Stack with the TextField on the bottom and faded Text widget above it. Obviously the text widget doesn't need to be faded but I was just mimicking the style of regular labels.
class CenteredTextField extends StatelessWidget {
final String label;
final TextEditingController controller;
CenteredTextField({
#required this.label,
this.controller,
});
#override
Widget build(BuildContext context) {
return Stack(
alignment: Alignment.topCenter,
children: [
Padding(
padding: EdgeInsets.only(top: 12.5),
child: TextField(
textAlign: TextAlign.center,
controller: controller,
),
),
Padding(
padding: EdgeInsets.only(top: 4.0),
child: Opacity(
opacity: 0.7,
child: Text(label),
),
),
],
);
}
}
You can Style TextFormField with Centered Text and Centered Label in Flutter
by using textAlign and floatingLabelAlignment property. I use Flutter 2.10.4
TextFormField(
controller: textController,
textAlign: TextAlign.center,
decoration:
InputDecoration(
border: const OutlineInputBorder(
borderRadius: BorderRadius.all(Radius.circular(5.0))),
isDense: true,
labelText: 'Label',
hintText: 'Hint',
floatingLabelAlignment: FloatingLabelAlignment.center,
floatingLabelStyle: const TextStyle(fontSize: 16),
labelStyle: const TextStyle(
fontSize: 13, color: Color.fromARGB(255, 152, 121, 11))),
)
Alignment for the label text appears in the screenshot is due to the presence of Prefix Icon. Label text will make a spacing according to the prefix icon present.
And for you, below is the same exact thing that makes the above design.
TextField(
textAlign: TextAlign.center,
decoration: InputDecoration(
prefixIcon: Icon(Icons.card_giftcard),
hintText: 'Hint Text',
labelText:'Label',
border: const OutlineInputBorder(),
),
)
Try and let know, if that helps you.
EDIT: I think there is no proper way to align the label text alone.
you can use the contentPadding: EdgeInsets.only(left: <Any_value>), property to move the label text
In My case, I need the text field to show some information and update them. So basically I am not strict about sticking with the labelText. So, I done the following trick to center the text.
Instead of using a label text you can use the Text itself and center it with textAlign property.
textAlign: TextAlign.center
By using the controller, you can assign a text to the text field. Also, you can update the textfield if you need a labeltext like effect. (but no animation)
This is my code:
TextEditingController timeText = TextEditingController()..text = '12:24 AM';
...
TextField(
controller: timeText,
enabled: false,
style: TextStyle(fontSize: 20),
decoration: InputDecoration(
border: InputBorder.none,
hintText: 'Center the text',
alignLabelWithHint: true,
),
textAlign: TextAlign.center,
),
OUTPUT
Well, it's not perfect, but I achieved it by using Center() in the label. Sadly, it erases part of the upper border.
label: Center(child: Text('Label')),
You can achieve thus by using the textAlign property of the TextField and set it to TextALign.center.
Check the code below:
TextField(
// use the text align property
textAlign: TextAlign.center,
decoration: InputDecoration(
labelText: 'Yay, it works',
hintText: 'Center the text',
),
),
OUTPUT: