Show/Hide Passwords in Flutter's TextFormField
Asked Answered
V

6

20

I'm working on a TextFormField to accept passwords. I have set the suffix icon to have IconButton child to detect on click events and to toggle the obscuretext attribute of the TextFormField. The callback function for the iconButton gets called but the TextFormField doesn't get repainted. Any ideas on how to solve this?

static Widget buildTextFormField(String id, 
                               FormFieldValidator<String> validateField,
                               FormFieldSetter<String> saveField,
                               InputDecoration decoration,
                               EdgeInsetsGeometry paddingInfo,
                               EdgeInsetsGeometry marginInfo,
                               TextInputType keyboardType,
                               {bool obscureField:false, double width:328.0,
                                TextEditingController controller}
  ){
return Container(
  padding: paddingInfo,
  margin: marginInfo,
  width: width,
  child: TextFormField(
    key: Key(id),
    obscureText: obscureField,
    validator: validateField,
    onSaved: saveField,
    keyboardType: keyboardType,
    decoration: decoration,
    controller: controller,
  ),
);

}

InputDecoration passwordDecoration = InputDecoration(
   hintText: 'Password',
   labelText: 'Enter your password',
   suffixIcon:
      IconButton(
         icon: Icon(
            _passwordVisible ? Icons.visibility : Icons.visibility_off,
            semanticLabel: _passwordVisible ? 'hide password' : 'show password',
         ),
         onPressed: () {
            setState(() {
               _passwordVisible ^= true;
               //print("Icon button pressed! state: $_passwordVisible"); //Confirmed that the _passwordVisible is toggled each time the button is pressed.
            });
         }),
   labelStyle: TextStyle(
      fontFamily: 'Roboto Medium',
      fontSize: 12.0,
      color: Color(0x99000000),
      letterSpacing: 0.4,
   ),
);
final passwordPaddingInfo = const EdgeInsets.only(top: 15.0, bottom:15.0,
                                                  left: 22.0, right:25.0);
this._passwordField = AdministrationComponents.
buildTextFormField('passwordField', validatePassword,
   (value) => _password = value, passwordDecoration, passwordPaddingInfo,
   null, null, controller:_passwordController,
   obscureField: !_passwordVisible);
Verism answered 3/1, 2019 at 5:56 Comment(9)
Please update your question adding the code instead of the image.Archetype
@Archetype please see update. Thanks!Verism
is your password visible when you press the eye-Icon ? what's the issue? paste your build methodArchetype
Are you calling the buildTextFormField in your build() method ?Arrowy
@Archetype No, it not visible when I press the IconButton. However, I see that the value of _passwordVisible toggles when the button is pressed.Verism
@ShyjuM yes, I am.Verism
I am actually calling the buildTextFormField from within the constructor of a class that is derived from State<T>. See the build method below. All the children of the ListView are initialized in the constructor. @override Widget build(BuildContext context) { return Form( key: _formKey, child: ListView( children: [ _appLogo, _fullnameField, _emailField, _passwordField, _confirmPasswordField, _registerButton, ], ) ); }Verism
working fine for me with your code. github.com/shyjuzz/flutter-samples/tree/master/passworddemoArrowy
@ShyjuM Thanks for trying it out. I see what I was doing wrong - I was calling the buildTextFormField in the constructor of my State class and not in the build method. Moving the call to buildTextFormField inside the build method fixed it. Thanks again for all of your help!Verism
V
2

Thanks @ShyjuM and @ diegoveloper! I see what I was doing wrong - I was calling the buildTextFormField in the constructor of my State class and not in the build method. Moving the call to buildTextFormField inside the build method fixed it. Thanks again for all of your help!

Verism answered 3/1, 2019 at 7:3 Comment(0)
S
18

Try to this

 bool _showPassword = false;
  void _togglevisibility() {
    setState(() {
      _showPassword = !_showPassword;
    });
  }

Textform field code

child: TextFormField(
                                controller: _passwordController,
                                obscureText: !_showPassword,
                                cursorColor: Colors.red,
                                style: TextStyle(color: Colors.white),
                                decoration: InputDecoration(
                                  hintText: "Password",
                                  border: InputBorder.none,
                                  suffixIcon: GestureDetector(
                                    onTap: () {
                                      _togglevisibility();
                                    },
                                    child: Icon(
                                      _showPassword ? Icons.visibility : Icons
                                          .visibility_off, color: Colors.red,),
                                  ),
                                ),
                              ),
Sole answered 29/4, 2020 at 13:10 Comment(0)
I
9

Show/Hide Passwords in Flutter's TextFormField

Step 1:

bool _obscureText = true;

Step 2:

void _toggle() {
    setState(() {
      _obscureText = !_obscureText;
    });
  }

Step 3:

 TextField(
                controller: password,
                style: TextStyle(fontSize: 16.0),
                obscureText: _obscureText,
                decoration: new InputDecoration(
                  border: InputBorder.none,
                  focusedBorder: InputBorder.none,
                  enabledBorder: InputBorder.none,
                  errorBorder: InputBorder.none,
                  disabledBorder: InputBorder.none,
                  hintText: "Password",
                  suffixIcon: InkWell(
                    onTap: _toggle,
                    child: Icon(
                      _obscureText
                          ? FontAwesomeIcons.eye
                          : FontAwesomeIcons.eyeSlash,
                      size: 15.0,
                      color: Colors.black,
                    ),
                  ),
                ),
              ),
Imperceptible answered 21/5, 2019 at 6:55 Comment(1)
adding an explanation to your answer would help.Hornback
V
2

Thanks @ShyjuM and @ diegoveloper! I see what I was doing wrong - I was calling the buildTextFormField in the constructor of my State class and not in the build method. Moving the call to buildTextFormField inside the build method fixed it. Thanks again for all of your help!

Verism answered 3/1, 2019 at 7:3 Comment(0)
A
1

You have some errors in your code.

Replace this :

_passwordVisible > Icons.visibility : Icons.visibility_off,

and

_passwordVisible ^= true;

By this:

_passwordVisible ? Icons.visibility : Icons.visibility_off,

and

  _passwordVisible = !_passwordVisible;
Archetype answered 3/1, 2019 at 6:28 Comment(2)
thanks for catching that. But it was actually a typo from me converting the image I originally posted to text. I have corrected it in the snippet above. and _passwordVisible ^= true; is equivalent to _passwordVisible = !_passwordVisible;Verism
thanks @Archetype for trying it out. I see what I was doing wrong - I was calling the buildTextFormField in the constructor of my State class and not in the build method. Moving the call to buildTextFormField inside the build method fixed it. Thanks again for all of your help!Verism
F
0

Try this.

I have used obscureText for hiding the text

import 'package:flutter/material.dart';

class PasswordTextFiled extends StatefulWidget {
  const PasswordTextFiled({super.key});

  @override
  State<PasswordTextFiled> createState() => _PasswordTextFiledState();
}

class _PasswordTextFiledState extends State<PasswordTextFiled> {
  bool isPasswordVisible = true;
  @override
  Widget build(BuildContext context) {
    return TextField(
      onChanged: (value) {},
      obscureText: isPasswordVisible,
      decoration: InputDecoration(
        suffixIcon: IconButton(
            onPressed: () {
              setState(() {
                isPasswordVisible = !isPasswordVisible;
              });
            },
            icon: Icon(
              isPasswordVisible
                  ? Icons.visibility_outlined
                  : Icons.visibility_off_outlined,
            )),
        label: const Text(
          "Password",
        ),
      ),
    );
  }
}
Farmyard answered 25/5 at 16:33 Comment(0)
D
-1

This is the Password dart i use

import 'package:flutter/material.dart';
class LoginPass extends StatefulWidget {
LoginPass(this.controllerUpass);

  final Function controllerUpass;

  @override
  _LoginPassState createState() => _LoginPassState();
}

class _LoginPassState extends State<LoginPass> {
  bool _isHidden = true;
  @override
  Widget build(BuildContext context) {
    return Padding(
      padding: EdgeInsets.fromLTRB(0, 30, 0, 10),
      child: Container(
        height: 35,
        child: Center(
          child: Padding(
            padding: const EdgeInsets.only(left: 20),
            child: TextField(
              obscureText: _isHidden,
              onChanged: (value) {
                widget.controllerUpass(value);
              },
              decoration: InputDecoration(
                  hintText: 'Password',
                  border: InputBorder.none,
                  focusedBorder: InputBorder.none,
                  enabledBorder: InputBorder.none,
                  errorBorder: InputBorder.none,
                  disabledBorder: InputBorder.none,
                  suffixIcon: GestureDetector(
                    onTap: () {
                      setState(() {
                        _isHidden = !_isHidden;
                      });
                    },
                    child: _isHidden
                        ? Icon(
                            Icons.remove_red_eye_sharp,
                            color: Colors.blue,
                          )
                        : Icon(
                            Icons.remove_red_eye,
                            color: Colors.red,
                          ),
                  )),
            ),
          ),
        ),
        decoration: BoxDecoration(
          boxShadow: <BoxShadow>[
            BoxShadow(
              color: Colors.black26,
              spreadRadius: 1,
              blurRadius: 3,
              offset: Offset(0, 3),
            ),
          ],
          color: Colors.white,
          borderRadius: BorderRadius.all(Radius.circular(3)),
        ),
      ),
    );
  }
}

In Main call

LoginPass(controllerUpass),
Deaminate answered 12/9, 2020 at 3:38 Comment(1)
child: Icon(_isHidden?Icons.visibility:Icons.visibility_off) this seems more efficientMalda

© 2022 - 2024 — McMap. All rights reserved.