Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to move label text to top of the input text field only when I type some text

Tags:

flutter

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)),
      ),
    );
  }

like image 478
Nishant Singh Avatar asked Aug 09 '19 07:08

Nishant Singh


People also ask

Is it possible to float labels in form input?

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.

What is the best way to position text labels?

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.

How to create a column of text labels next to form elements?

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:

How do I align the input labels to the right?

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!


2 Answers

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: enter image description here

like image 172
anmol.majhail Avatar answered Oct 07 '22 22:10

anmol.majhail


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

like image 24
Tadija Bagarić Avatar answered Oct 07 '22 23:10

Tadija Bagarić