I want to move the label text to top of the input text field only when I enter some text. Currently it is moving on top when input text field is getting focus.
Widget nameField() {
return TextFormField(
keyboardType: TextInputType.text,
autofocus: false,
textAlign: TextAlign.start,
textInputAction: TextInputAction.done,
controller: nameTextEditingController,
style: TextStyle(
color: Colors.white, fontSize: 18, fontWeight: FontWeight.w500),
decoration: const InputDecoration(
contentPadding: EdgeInsets.symmetric(vertical: 15),
labelText: Strings.user_info_page_name_placeholder,
labelStyle: TextStyle(
color: Colors.grey, fontSize: 18, fontWeight: FontWeight.w500),
focusedBorder: OutlineInputBorder(
borderSide: BorderSide(color: Colors.transparent, width: 1)),
),
);
}
It looks amazing seeing labels animating and changing their position to the top of the input and staying itself there when input is filled with some text. Here is a demo with source code to float labels or input placeholder on top on focus and while typing inside form-input.
Using Top-positioned Text Labels. Positioning labels at the top of their form elements is probably the easiest layout to achieve, as we only need to tell the label to take up the entire width of its parent element.
When we create a column of text labels to the left of the form elements, we’ll have to do a little bit more work than just to position them at the top. Once we begin floating elements, all hell breaks loose! In order to position the labels next to the form elements, we float the label elements to the left and give them an explicit width:
With all that difficult floating safely out of the way, aligning the input labels to the right is a breeze; simply set the text alignment on the label elements to achieve a form that looks like the image below: And we’re done! Now you can take your pick of whichever form layout best fits your pages, all by changing a little CSS!
I can think of two ways of doing this. Trick here is to use hintText:
First: using onChanged:
method.
Code:
class MyClass extends StatefulWidget {
@override
_MyClassState createState() => new _MyClassState();
}
class _MyClassState extends State<MyClass> with SingleTickerProviderStateMixin {
TextEditingController nameTextEditingController = TextEditingController();
String _labelText;
@override
void initState() {
super.initState();
// nameTextEditingController.addListener(_hasStartedTyping);
}
// void _hasStartedTyping() {
// setState(() {
// if (nameTextEditingController.text.isNotEmpty) {
// _labelText = 'Name';
// } else {
// _labelText = null;
// }
// });
// }
@override
Widget build(BuildContext context) {
return Scaffold(
body: Padding(
padding: EdgeInsets.symmetric(horizontal: 25, vertical: 30),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
TextFormField(
keyboardType: TextInputType.text,
autofocus: false,
textAlign: TextAlign.start,
onChanged: (v){
setState(() {
if(v.isNotEmpty){
_labelText = 'Name';
}else{
_labelText = null;
}
});
},
textInputAction: TextInputAction.done,
controller: nameTextEditingController,
style: TextStyle(
color: Colors.black87,
fontSize: 18,
fontWeight: FontWeight.w500),
decoration: InputDecoration(
contentPadding: EdgeInsets.symmetric(vertical: 15),
labelText: _labelText,
hintText: 'Name',
hintStyle: TextStyle(
color: Colors.grey,
fontSize: 18,
fontWeight: FontWeight.w500),
labelStyle: TextStyle(
color: Colors.grey,
fontSize: 18,
fontWeight: FontWeight.w500),
focusedBorder: OutlineInputBorder(
borderSide:
BorderSide(color: Colors.transparent, width: 1)),
),
),
],
)),
);
}
}
Second: using TextEditingController.addListener()
method.
Code:
class MyClass extends StatefulWidget {
@override
_MyClassState createState() => new _MyClassState();
}
class _MyClassState extends State<MyClass> with SingleTickerProviderStateMixin {
TextEditingController nameTextEditingController = TextEditingController();
String _labelText;
@override
void initState() {
super.initState();
nameTextEditingController.addListener(_hasStartedTyping);
}
void _hasStartedTyping() {
setState(() {
if (nameTextEditingController.text.isNotEmpty) {
_labelText = 'Name';
} else {
_labelText = null;
}
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Padding(
padding: EdgeInsets.symmetric(horizontal: 25, vertical: 30),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
TextFormField(
keyboardType: TextInputType.text,
autofocus: false,
textAlign: TextAlign.start,
// onChanged: (v){
// setState(() {
// if(v.isNotEmpty){
// _labelText = 'Name';
// }else{
// _labelText = null;
// }
// });
//
// },
textInputAction: TextInputAction.done,
controller: nameTextEditingController,
style: TextStyle(
color: Colors.black87,
fontSize: 18,
fontWeight: FontWeight.w500),
decoration: InputDecoration(
contentPadding: EdgeInsets.symmetric(vertical: 15),
labelText: _labelText,
hintText: 'Name',
hintStyle: TextStyle(
color: Colors.grey,
fontSize: 18,
fontWeight: FontWeight.w500),
labelStyle: TextStyle(
color: Colors.grey,
fontSize: 18,
fontWeight: FontWeight.w500),
focusedBorder: OutlineInputBorder(
borderSide:
BorderSide(color: Colors.transparent, width: 1)),
),
),
],
)),
);
}
}
Output:
Know this was asked some time ago and the given answer probably worked for the time, but since this is the first hit on Google I'll add this more up-to-date answer
InputDecoration
has floatingLabelBehavior property.
So adding floatingLabelBehavior: FloatingLabelBehavior.auto
to your InputDecoration
would do what you want.
So:
TextFormField(
decoration: const InputDecoration(
labelText: "Click me",
floatingLabelBehavior: FloatingLabelBehavior.auto),
),
DartPad: https://dartpad.dev/?ffc1844e90bb8343d90b14c7887c9de1
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With