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.
This has been very confusing to me since the TextField wrapped in a SizedBox only, works perfectly; but it appears to be a simple image (it can't be tapped, nor focused) when I wrap that same piece of code in a Transform.translate widget.
Also, if I change the Transform.translate to a Positioned widget, the TextField works perfectly, but I'd like to understand why this is happening, because I am required to use Transform.translate over Positioned for this special project.
class Login extends StatelessWidget {
Login({
Key key,
}) : super(key: key);
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: const Color(0xfff4f6fa),
body: Stack(
children: <Widget>[
SizedBox(
width: 302.0,
height: 60.0,
child: TextField(
decoration: InputDecoration(
hintText: 'Correo electrónico *',
prefixIcon: Icon(Icons.send),
border: OutlineInputBorder(
borderSide:
BorderSide(width: 1.0, color: const Color(0xffe7e7e7)),
borderRadius: BorderRadius.circular(4.0),
),
),
style: TextStyle(
fontFamily: 'Nunito',
fontSize: 14,
color: const Color(0xff777777),
height: 1.4285714285714286,
),
textAlign: TextAlign.left,
onChanged: (String value) async {
},
onSubmitted: (String value) async {
},
),
),
// Positioned(
Transform.translate(
offset: Offset(36.0, 317.8),
// left: 36,
// top: 317.8,
child:
// Adobe XD layer: 'input:mail' (component)
SizedBox(
width: 302.0,
height: 60.0,
child: TextField(
decoration: InputDecoration(
hintText: 'Correo electrónico *',
prefixIcon: Icon(Icons.send),
border: OutlineInputBorder(
borderSide:
BorderSide(width: 1.0, color: const Color(0xffe7e7e7)),
borderRadius: BorderRadius.circular(4.0),
),
),
style: TextStyle(
fontFamily: 'Nunito',
fontSize: 14,
color: const Color(0xff777777),
height: 1.4285714285714286,
),
textAlign: TextAlign.left,
onChanged: (String value) async {
},
onSubmitted: (String value) async {
},
),
),
),
],
),
);
}
}
As mentioned before, both inputs show on the screen (one at the center and one at the top) only the TextField wrapped with a SizeBox (first element of the Stack, at the top of the sreen)can be tapped, nothing happens when the one at the center of the screen (second element of the stack, located there because of the translation) is tapped.
Try debugging and see the layout grid lines and correct boundaries of widget using Flutter inspector.
That should give you a better idea at why is it behaving this way.
Seems like when You use the Transform widget, it doesnt register the hit as it merely moves the boundaries and not the tap area.
Try wrapping the Transform widget with a GestureDetector and see.
You can also follow a similar issue on GitHub:
https://github.com/flutter/flutter/issues/27587
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,
),
),
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:
I want to add the text through a container border in flutter.
I just want that Address to appear through a gap between the top border. It doesn't seem possible using a positioned widget, because then the border lines would appear through the "Address" text.
Is it at all possible?
Is this what you want?
class MainPage extends StatefulWidget {
#override
_MainPageState createState() => _MainPageState();
}
class _MainPageState extends State<MainPage> {
FocusNode focusNode = FocusNode();
bool isFocused = false;
#override
void initState() {
focusNode.addListener(_onFocusChange);
super.initState();
}
void _onFocusChange() {
setState(() => isFocused = !isFocused);
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: Container(
margin: const EdgeInsets.symmetric(horizontal: 500, vertical: 300),
child: Stack(
children: <Widget>[
Container(
padding: const EdgeInsets.only(top: 10),
child: TextFormField(
focusNode: focusNode,
decoration: InputDecoration(
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(30)),
),
),
),
Align(
alignment: Alignment.topCenter,
child: Container(
color: Colors.white,
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 8.0),
child: Text(
'Address',
style:
isFocused ? TextStyle(color: Colors.blue[800]) : null,
),
),
),
),
],
),
),
);
}
}
As far as I know there is no way to centerized labelText in InputDecoration.
Does it have to be the container border? If not, you can use the TextField with InputDecoration like this:
TextField(
decoration: InputDecoration(
border: OutlineInputBorder(),
labelText: 'Label Text',
),
textAlign: TextAlign.center,
),
But Sadly the TextField dose not support the centered label text (textAlign: TextAlign.center, only centers the hint text). If you want to center the label text you have to change the TextField.dart.
This is TextField so it's not like a usual Text because it is editable. If you want it to be like a Text,set enabled: false and give a controller to it and set an initial value. Or you can use TextFormField so you don't have to use a controller. Like this:
TextFormField(
decoration: InputDecoration(
border: OutlineInputBorder(),
labelText: 'Address',
),
textAlign: TextAlign.center,
enabled: true,
initialValue: 'Address Here',
),