How to move label text to top of the input text field only when I type some text
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)),
),
);
}
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