Search code examples
flutterdartflutter-layout

How can I keep the IconButton inside a TextField from focusing the text field when the button is pressed?


Here is my code for the text field inside my scaffold:

child: TextField(
  obscureText: _obscureText,
  controller: myController2,
  focusNode: myFocusNode2,
  textInputAction: TextInputAction.done,
  onSubmitted: (value){
    myFocusNode2.unfocus();
    _loginMethod();
  },
  decoration: InputDecoration(
    labelText: "Password",
    border: OutlineInputBorder(),
    suffixIcon: IconButton(
      icon: Icon(_obscureText ? Icons.visibility_off: Icons.visibility),
      onPressed: (){
        setState(() {
          _obscureText = !_obscureText;
        });
        Timer.run(() => myFocusNode2.unfocus());
      },
    )
  ),
),

What I have right now works, but it is not clean at all. Most of the time the text field becomes focused for a second then the .unfocus() unfocuses it after a delay, so I get this jump effect with the keyboard popping up and then going back down. Only a few times the text field will never get focused at all and I don't understand why.

Is there a way to make sure the IconButton never focuses the text field when it is pressed?


Solution

  • I just can think of 3 solutions, not prefect but just get the job done

    1- use focusNode with timer

    after you link foucsNode to the textfiled the button function could be something like this

              onPressed: () {
                Timer.periodic(Duration(microseconds: 1), (_) {
                  focusNode.unfocus();
                });
                //Write your code here
              },
    

    2- use stack

    Stack(
              alignment: Alignment.centerRight,
              children: <Widget>[
                TextField(
                  decoration: InputDecoration(
                    labelText: "Password",
                    border: OutlineInputBorder(),
                  ),
                ),
                IconButton(
                  icon: Icon(Icons.ac_unit),
                  onPressed: () {
                    //do any thing
                  },
                ),
              ],
            ),
    

    3- as Afridi Kayal said you can use a row

    Row(
              children: <Widget>[
                Expanded(
                  child: TextField(
                    focusNode: focusNode,
                    enabled: enabled,
                    autofocus: false,
                    textInputAction: TextInputAction.done,
                    decoration: InputDecoration(
                      labelText: "Password",
                      border: OutlineInputBorder(),
                    ),
                  ),
                ),
                IconButton(
                  icon: Icon(Icons.visibility),
                  onPressed: () {
                    print('object');
                  },
                ),
              ],
            ),
    

    if you end up going with number 2 or 3 and you want to make the button color change when you focus on the textfiled, you can do it by using focusNode as well.