How to show/hide password in TextFormField?

前端 未结 9 1247
故里飘歌
故里飘歌 2021-02-01 00:54

Currently I have my password TextFormField like this:

TextFormField(
  decoration: const InputDecoration(
         


        
相关标签:
9条回答
  • 2021-02-01 00:57
      bool _obscuredText = true; 
    
      _toggle(){
        setState(() {
          _obscuredText = !_obscuredText;
        });
      }
    
      Widget _createPassword(){
        return TextField(
          obscureText: _obscuredText,
          cursorColor: Colors.black54,
          style: TextStyle( color: Colors.black54),
          decoration: InputDecoration(
            labelStyle: TextStyle(
                color: Colors.black54
            ),
            focusedBorder: OutlineInputBorder(
                borderSide: BorderSide(
                    color: Colors.black54
                )
            ),
            border: OutlineInputBorder(
                borderRadius: BorderRadius.circular(5.0)
            ),
            labelText: 'Contraseña',
            hintText: 'Contraseña',
            suffixIcon: FlatButton(onPressed: _toggle, child:Icon(Icons.remove_red_eye, color: _obscuredText ? Colors.black12 : Colors.black54))
          ),
          onChanged: (value) {
            setState(() {
              _password = value;
            });
          },
        );
      }
    

    Hope this helps!

    0 讨论(0)
  • 2021-02-01 00:58

    Well I personally like to keep the passwords hidden all the time and seen when you want to see them, so this is the approach I use to hide/unhide passwords,Incase you want the password to be visible when the touch is In contact with the hide icon, and hidden as soon as you remove the contact then this is for you

    //make it invisible globally
      bool invisible = true;
    
    //wrap your toggle icon in Gesture Detector
      GestureDetector(
       onTapDown: inContact,//call this method when incontact
       onTapUp: outContact,//call this method when contact with screen is removed
       child: Icon(
       Icons.remove_red_eye,
       color: colorButton,
       ),
      ),
    
      void inContact(TapDownDetails details) {
        setState(() {
          invisible = false;
        });
      }
    
      void outContact(TapUpDetails details) {
        setState(() {
          invisible=true;
        });
      }
    

    I have also published this as a package here https://pub.dev/packages/passwordfield

    The output of the above code

    0 讨论(0)
  • 2021-02-01 01:01

    With a credit goes to X-Wei, you can create the widget as a separate password.dart:

    import 'package:flutter/material.dart';
    
    class PasswordField extends StatefulWidget {
      const PasswordField({
        this.fieldKey,
        this.hintText,
        this.labelText,
        this.helperText,
        this.onSaved,
        this.validator,
        this.onFieldSubmitted,
      });
    
      final Key fieldKey;
      final String hintText;
      final String labelText;
      final String helperText;
      final FormFieldSetter<String> onSaved;
      final FormFieldValidator<String> validator;
      final ValueChanged<String> onFieldSubmitted;
    
      @override
      _PasswordFieldState createState() => new _PasswordFieldState();
    }
    
    class _PasswordFieldState extends State<PasswordField> {
      bool _obscureText = true;
    
      @override
      Widget build(BuildContext context) {
        return new TextFormField(
          key: widget.fieldKey,
          obscureText: _obscureText,
          maxLength: 8,
          onSaved: widget.onSaved,
          validator: widget.validator,
          onFieldSubmitted: widget.onFieldSubmitted,
          decoration: new InputDecoration(
            border: const UnderlineInputBorder(),
            filled: true,
            hintText: widget.hintText,
            labelText: widget.labelText,
            helperText: widget.helperText,
            suffixIcon: new GestureDetector(
              onTap: () {
                setState(() {
                  _obscureText = !_obscureText;
                });
              },
              child:
              new Icon(_obscureText ? Icons.visibility : Icons.visibility_off),
            ),
          ),
        );
      }
    }
    

    Call it as:

      import 'package:my_app/password.dart';
    
      String _password;
      final _passwordFieldKey = GlobalKey<FormFieldState<String>>();
    
      PasswordField(
        fieldKey: _passwordFieldKey,
        helperText: 'No more than 8 characters.',
        labelText: 'Password *',
        onFieldSubmitted: (String value) {
          setState(() {
            this._password = value;
          });
        },
      ),
    
    0 讨论(0)
  • 2021-02-01 01:07

    I did it with holding and releasing the longTap:

        bool _passwordVisible;
    
    @override
    void initState() {
        _passwordVisible = false;
        super.initState();
    }
    
    // ...
    TextFormField(
      obscureText: !_passwordVisible,
      decoration: InputDecoration(
        hasFloatingPlaceholder: true,
        filled: true,
        fillColor: Colors.white.withOpacity(0.5),
        labelText: "Password",
        suffixIcon: GestureDetector(
          onLongPress: () {
            setState(() {
              _passwordVisible = true;
            });
          },
          onLongPressUp: () {
            setState(() {
              _passwordVisible = false;
            });
          },
          child: Icon(
              _passwordVisible ? Icons.visibility : Icons.visibility_off),
        ),
      ),
      validator: (String value) {
        if (value.isEmpty) {
          return "*Password needed";
        }
      },
      onSaved: (String value) {
        _setPassword(value);
      },
    );
    
    0 讨论(0)
  • 2021-02-01 01:08

    Thank @Parikshit Chalke for answer. However, setState is quite expensive call if your only want to update your TextFormField and IconButton. Instead, wrap it inside StatefulBuilder and have only child items updated.

    Example solution:

    import 'package:flutter/material.dart';
    
    class MyWidget extends StatefulWidget {
      @override
      _MyWidgetState createState() => _MyWidgetState();
    }
    
    class _MyWidgetState extends State<MyWidget> {
      // initially password is invisible
      bool _passwordVisible = false;
      String _password;
    
      @override
      Widget build(BuildContext context) {
        return Column(
          children: [
            // other widget that does not need update when password visibility is toggled
            Text("I do not require update"),
            
            StatefulBuilder(builder: (_context, _setState) {
              // only following widget gets update when _setState is used
              return TextFormField(
                decoration: InputDecoration(
                  suffixIcon: IconButton(
                    icon: Icon(
                      _passwordVisible ? Icons.visibility : Icons.visibility_off,
                    ),
                    onPressed: () {
                      // use _setState that belong to StatefulBuilder
                      _setState(() {
                        _passwordVisible = !_passwordVisible;
                      });
                    },
                  ),
                  labelText: 'Password',
                  icon: const Padding(
                    padding: const EdgeInsets.only(top: 15.0),
                    child: const Icon(Icons.lock),
                  ),
                ),
                validator: (val) => val.length < 6 ? 'Password too short.' : null,
                onSaved: (val) => _password = val,
                obscureText: true,
              );
            }),
          ],
        );
      }
    }
    
    
    0 讨论(0)
  • 2021-02-01 01:12

    First make you widget StatefulWidget if it is a StatelessWidget.

    Then have a variable bool _obscureText and pass it to your TextFormField. The toggle it with setState as required.

    Example:

    class _FormFieldSampleState extends State<FormFieldSample> {
    
      // Initially password is obscure
      bool _obscureText = true;
    
      String _password;
    
      // Toggles the password show status
      void _toggle() {
        setState(() {
          _obscureText = !_obscureText;
        });
      }
    
      @override
      Widget build(BuildContext context) {
        return new Scaffold(
          appBar: new AppBar(
            title: new Text("Sample"),
          ),
          body: new Container(
            child: new Column(
              children: <Widget>[
                new TextFormField(
                  decoration: const InputDecoration(
                      labelText: 'Password',
                      icon: const Padding(
                          padding: const EdgeInsets.only(top: 15.0),
                          child: const Icon(Icons.lock))),
                  validator: (val) => val.length < 6 ? 'Password too short.' : null,
                  onSaved: (val) => _password = val,
                  obscureText: _obscureText,
                ),
                new FlatButton(
                    onPressed: _toggle,
                    child: new Text(_obscureText ? "Show" : "Hide"))
              ],
            ),
          ),
        );
      }
    }
    

    Hope this helps!

    0 讨论(0)
提交回复
热议问题