so i have a text field in witch the user will enter the password and i want to display at the end that icon if the user click on it it will show the password else it's going to hidden . the text field is inside the container basically as shown in the picture . How to do it ?
Container(
height: MediaQuery.of(context).size.height * 0.08,
margin: const EdgeInsets.symmetric(horizontal: 5),
decoration: BoxDecoration(
color: const Color(0xFFEFEDED),
border: Border.all(color: Colors.transparent),
borderRadius: BorderRadius.circular(10),
),
child: Padding(
padding: const EdgeInsets.only(left: 8.0),
child: Row(
children: [
Icon(Icons.remove_red_eye_outlined),
TextFormField(
controller: controller,
keyboardType:
isUrl ? TextInputType.url : TextInputType.text,
decoration: const InputDecoration(
border: InputBorder.none,
),
),
],
),
),
)
,
The following code enable and toggles the show/hide text by pressing the "eye" button on the far right.
It works with a boolean variable.
Remember to have a Stateful Widget.
bool hidden;
#override
void initState() {
hidden = true;
super.initState();
}
TextFormField(
controller: controller,
obscureText: hidden,
keyboardType: isUrl ? TextInputType.url : TextInputType.text,
decoration: InputDecoration(
border: InputBorder.none,
suffixIcon: IconButton(
onPressed: () => setState(() {
hidden = !hidden;
}),
icon: const Icon(Icons.remove_red_eye_outlined))),
)
Related
I have a text field with a value. But I ran into a problem that I need to add icons next to the value in addition to the value. I can add one icon using suffixIcon. But I will need to add 3 icons, sometimes add 2 icons but I don't know how to add more than one icon to the text field?
Widget _defaultTextfield(
bool enabled,
TextInputType? type,
String hint,
String val,
BuildContext context,
) {
final MycarsCubit cubit = BlocProvider.of<MycarsCubit>(context);
return SizedBox(
height: 58,
child: Card(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8),
),
color: constants.Colors.greyMiddle,
child: Row(
children: [
Flexible(
child: TextField(
style: constants.Styles.smallTextStyleWhite,
keyboardType: type,
controller: TextEditingController(text: '$val kW'),
onChanged: (value) {
cubit.change(
carModelNew: cubit.carModel,
idText: cubit.id,
modelText: cubit.model,
numberText: value,
typeText: cubit.type,
yearText: cubit.year,
chargeSpeedText: cubit.chargeSpeed,
connectorText: cubit.connector,
batteryCapacityText: cubit.batteryCapacity,
mainNew: cubit.main,
);
},
decoration: InputDecoration(
border: InputBorder.none,
enabled: enabled,
contentPadding: const EdgeInsets.all(8),
labelText: hint,
labelStyle: constants.Styles.textFieldLabelLightGreyStyle,
suffixIcon: const Icon(Icons.bolt),
suffixIconConstraints: BoxConstraints(
maxHeight: 10
)
),
),
),
],
),
),
);
}
You can do this:
TextField(
decoration: InputDecoration(
suffixIcon: Row(
children: [
Icon(Icons.bolt),
value == 10 ? Icon(Icons.bolt):SizedBox(),
],
)),
)
I have to make one application which take so many user input , that's why i use so many Textfiled in my code for taking user input.
An Textfiled validation time I simply use List of Global keys and it's work perfactly.
But problem is when user give wrong input then textfiled show an error message that time my Textbox UI can change (UI well change in very appropriately).
Pleas help , what can i do so my error message postion will be changed.
TextFiled code :
//this is inside the statfull Widget
GlobalKey<FormState> _formkeySubNumber = new GlobalKey();
Widget SubNumber_Input_Box() {
return Form(
//for form validation
key: _formkeySubNumber,
child: Container(
margin: EdgeInsets.only(top: 7, left: 6),
height: 38,
width: 300,
decoration: BoxDecoration(
color: HexColor("#D9D9D9"),
borderRadius: BorderRadius.all(Radius.circular(10)),
),
//padding
child: Padding(
padding: EdgeInsets.only(left: 12),
//textfiled
child: TextFormField(
//for validation
validator: (value) {
if (value == null || value.isEmpty) {
return 'Please Enter Subject Number';
}
return null;
},
//for storing user input && value in string format so we convert into the int formate
onChanged: (value) {
subjectNumber = int.tryParse(value)!;
},
//for only number
keyboardType: TextInputType.number,
decoration: const InputDecoration(
hintText: "Enter Minimum-4 to Maximum-8 Subject",
hintStyle: TextStyle(
fontFamily: "RobotoSlab",
fontSize: 14,
),
//for remove underline from input filed
border: InputBorder.none,
),
//for store only integer value
inputFormatters: <TextInputFormatter>[
FilteringTextInputFormatter.allow(RegExp(r'[0-9]')),
],
),
),
),
);
}
And this call inside the one Button Like that
[Container(
margin: EdgeInsets.only(top: 5),
child: ElevatedButton(
child: Text("Go"),
style: ElevatedButton.styleFrom(
primary: HexColor("#EE6C4D"),
//this colour set (opacity is low) when button is disable
onSurface: HexColor("#E0FBFC"),
),
//store user value -->subjectNumber
onPressed: isGoButtonActive
? () {
//for Form Validation
if (_formkeySubNumber.currentState!
.validate()) {
//this show the container after prerssed button
showContainer1();
}
setState(() {
// //this is for store subjectnumber value from user input
// subjectNumber =
// subNumber_Controller.text;
// print("Subject Number Is : $subjectNumber");
});
}
: null,
),
),]
You have created a container around the textfield with specific height. For styling a textfield you can use
TextField(
decoration: InputDecoration(
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(10.0),
),
filled: true,
hintStyle: TextStyle(color: Colors.grey),
hintText: "Type in your text",
fillColor: Colors.white),
)
This way the error message appears below the textfield and outside the white area.
You can remove the height from Form> Container. And it will give you flexible height based on error state.
Widget SubNumber_Input_Box() {
return Form(
key: _formkeySubNumber,
child: Container(
width: 300,
color: HexColor("#D9D9D9"),
//padding
child: Padding(
padding: EdgeInsets.only(left: 12),
child: TextFormField(
autovalidateMode: AutovalidateMode.onUserInteraction, // you might like this as well
Also I will suggest to look at OutlineInputBorder
Widget SubNumber_Input_Box() {
return Form(
key: _formkeySubNumber,
child: Padding(
padding: EdgeInsets.only(left: 12),
child: TextFormField(
autovalidateMode: AutovalidateMode.onUserInteraction,
//for validation
validator: (value) {
if (value == null || value.isEmpty) {
return 'Please Enter Subject Number';
}
return null;
},
//for storing user input && value in string format so we convert into the int formate
onChanged: (value) {
subjectNumber = int.tryParse(value)!;
},
//for only number
keyboardType: TextInputType.number,
decoration: const InputDecoration(
hintText: "Enter Minimum-4 to Maximum-8 Subject",
hintStyle: TextStyle(
fontFamily: "RobotoSlab",
fontSize: 14,
),
enabledBorder: OutlineInputBorder(),
errorBorder: OutlineInputBorder(),
focusedBorder: OutlineInputBorder(),
border: OutlineInputBorder(),
),
//for store only integer value
inputFormatters: <TextInputFormatter>[
FilteringTextInputFormatter.allow(RegExp(r'[0-9]')),
],
),
),
);
}
I have a stack widget that holds a background image and a textField widgets , I want the user to be able to change the position of the text onTap, I know how to get point details of the tap , but I don't know how to pass this information to textField to update its position
Edit: that's what I did so far, it works only to right or right, then it just disappears!! I think the problem in the coordinate details and use of stack and positioned widgets , but can't figure out how to fix it
Stack(children: [
SingleChildScrollView(
child: Container(
padding: EdgeInsets.all(16),
child: Card(
child: (finalsd == null)
? Image.file(File(_image.path))
: Image.file(File(finalsd!.path))))),
Positioned(
top: 25,
left: 50,
child: Visibility(
visible: caption_vis,
child: GestureDetector(
onTapDown: (details) {
setState(() {
positionHeight = details.localPosition.dx;
positionWidth = details.localPosition.dy;
print(positionWidth);
});
},
child: Container(
height: positionHeight,
width: positionWidth,
child: TextField(
controller: _controller,
focusNode: myFocusNode,
decoration: const InputDecoration(
border: InputBorder.none,
focusedBorder: InputBorder.none,
enabledBorder: InputBorder.none,
errorBorder: InputBorder.none,
disabledBorder: InputBorder.none,
),
onSubmitted: (String value) async {
//Your Code
},
),
)),
),
)
])
You can resize it by wrapping it with a TextField Container and updating the container height and width when the trigger you want occurs.
double? positionHeight = 0;
double? positionWidth = 0;
GestureDetector(
onTapDown: (details) {
setState(() {
positionHeight = 100;
positionWidth = 100;
});
},
child: Container(
height: positionHeight,
width: positionWidth,
child: TextField(
controller: _controller,
focusNode:myFocusNode ,
decoration: const InputDecoration(
border: InputBorder.none,
focusedBorder: InputBorder.none,
enabledBorder: InputBorder.none,
errorBorder: InputBorder.none,
disabledBorder: InputBorder.none,
),
onSubmitted: (String value) async {
//Your Code
},
),
)),
If you only want to position, not resize, you can set the Padding value this way.
EdgeInsetsGeometry textFieldPadding = EdgeInsets.all(8.0);
GestureDetector(
onTapDown: (details) {
setState(() {
textFieldPadding = const EdgeInsets.all(8.0);
textFieldPadding = EdgeInsets.zero;
textFieldPadding = EdgeInsetsGeometry.infinity;
textFieldPadding =
const EdgeInsets.symmetric(vertical: 10.0, horizontal: 10);
});
},
child: Padding(
padding: textFieldPadding,
child: TextField(
controller: _controller,
focusNode:myFocusNode ,
decoration: const InputDecoration(
border: InputBorder.none,
focusedBorder: InputBorder.none,
enabledBorder: InputBorder.none,
errorBorder: InputBorder.none,
disabledBorder: InputBorder.none,
),
onSubmitted: (String value) async {
//Your Code
},
),
),
);
First, Recently I have started to building desktop app with dart code.
just built some screens and which are responsible for mobile and web too, for that used LayoutBuilder
but going wrong with when trying to set the height according to mine, for that I wrapped TextformField with Container and gave height.
when I put validation on TextformField onClick of login button then something goes wrong with the height of TextformField.
Look at the Screenshot:
before of click the login button:
When I click the login button without inputting any value for checking validation:
Piece of code of TextformField :
Widget _buildEmailTextField() {
return Container(
height: 35,
child: Theme(
data: new ThemeData(
primaryColor: Color(0xFF262C48),
primaryColorDark: Color(0xFF262C48),
),
child: TextFormField(
keyboardType: TextInputType.emailAddress,
validator: (val){
bool emailValid = RegExp(r"^[a-zA-Z0-9.a-zA-Z0-9.!#$%&'*+-/=?^_`{|}~]+#[a-zA-Z0-9]+\.[a-zA-Z]+")
.hasMatch(val);
if(!emailValid){
return 'Invalid Email Address';
}else{
return null;
}
},
controller: emailController,
readOnly: isLoading?true:false,
decoration: InputDecoration(
fillColor: Color(0xFFd9d8d8),
filled: true,
border: new OutlineInputBorder(
borderRadius: const BorderRadius.all(
const Radius.circular(7.0),
),
borderSide: BorderSide(color:Color(0xFF262C48),width: 2.0)
),
contentPadding: EdgeInsets.only(left: 10),
// prefixIcon: Icon(
// Icons.email,
// color: Color(0xFF008577),
// ),
hintText: 'Email',
),
),
),
);
}
TextFormField inherits size from child. One of solution is to set contentPadding in InputDecoration.
You already use this to pad left side. You can do modification like below:
contentPadding: EdgeInsets.only(left: 10.0, top: 15.0, bottom: 15.0),
Please check it out,
Widget _buildEmailTextField()) {
return Container(
height: 35,
child: Theme(
data: new ThemeData(
primaryColor: Color(0xFF262C48),
primaryColorDark: Color(0xFF262C48),
),
child: Form(
key: _formKey,
child: Column(
children: [
SizedBox(
height: 20,
),
Container(
child: TextFormField(
keyboardType: TextInputType.emailAddress,
validator: (val) {
bool emailValid = RegExp(
r"^[a-zA-Z0-9.a-zA-Z0-9.!#$%&'*+-/=?^_`{|}~]+#[a-zA-Z0-9]+\.[a-zA-Z]+")
.hasMatch(val);
if (!emailValid) {
return 'Invalid Email Address';
} else {
return null;
}
},
controller: emailController,
readOnly: isLoading ? true : false,
decoration: InputDecoration(
fillColor: Color(0xFFd9d8d8),
filled: true,
border: new OutlineInputBorder(
borderRadius: const BorderRadius.all(
const Radius.circular(7.0),
),
borderSide:
BorderSide(color: Color(0xFF262C48), width: 2.0)),
contentPadding: new EdgeInsets.symmetric(
vertical: 25.0, horizontal: 10.0),
// prefixIcon: Icon(
// Icons.email,
// color: Color(0xFF008577),
// ),
hintText: 'Email',
),
),
),
RaisedButton(
onPressed: () {
// Validate returns true if the form is valid, otherwise false.
if (_formKey.currentState.validate()) {
// If the form is valid, display a snackbar. In the real world,
// you'd often call a server or save the information in a database.
Scaffold.of(context).showSnackBar(
SnackBar(content: Text('Processing Data')));
}
},
child: Text('Submit'),
)
],
),
),
),
);
}
return Container(
width: (screenWidth / 2) - 45,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
LightText(
text: widget.labelText,
),
Padding(
padding: EdgeInsets.only(top: 3),
),
Container(
height: 24,
decoration:
BoxDecoration(borderRadius: BorderRadius.circular(3)),
child: Theme(
data: ThemeData(hintColor: lightGrey),
child: TextField(
inputFormatters: [
WhitelistingTextInputFormatter.digitsOnly,
CurrencyInputFormatter(),
],
enabled: widget.enableVal,
controller: widget.controllerText,
keyboardType: TextInputType.number,
decoration: InputDecoration(
disabledBorder: OutlineInputBorder(
borderSide: BorderSide(color: Colors.white)),
border: OutlineInputBorder(),
contentPadding:
const EdgeInsets.symmetric(vertical: 3.0)),
))),
],
));
}
}
You can use the onChanged event of the Textfield to get the data whenever it changed.
Here is how you can do this.
String someData;
onChanged: (data) {
//data is your current value of the textfield.
someData = data;
},
Using it you will always have a Data of the TextField.
Edit
You can also use onSubmitted event too to get the result you want.
TextField(
onSubmitted: (data) {},
),
Use TextEditingController for this. Pseudo code sample:
TextEditingController _controller;
...
TextField(
controller: _controller,
),
...
void _someMethod(){
String text = _controller.text;
}
For listening the changes between focuses check this out: Focus and text fields
FocusNode _focus;
...
TextField(
focus: _focus;
)
...
void check(){
if(_focus.hasFocus){
// insert handling
}
}
I think there won't the best answer, until you check documentation by yourself.
Handle changes to a text field