How to show/hide password in TextFormField?
I have created a solution as per @Hemanth Raj but in a more robust way.
First declare a bool
variable _passwordVisible
.
Initiate _passwordVisible
to false
in initState()
@override void initState() { _passwordVisible = false; }
Following is the TextFormField
widget :
TextFormField( keyboardType: TextInputType.text, controller: _userPasswordController, obscureText: !_passwordVisible,//This will obscure text dynamically decoration: InputDecoration( labelText: 'Password', hintText: 'Enter your password', // Here is key idea suffixIcon: IconButton( icon: Icon( // Based on passwordVisible state choose the icon _passwordVisible ? Icons.visibility : Icons.visibility_off, color: Theme.of(context).primaryColorDark, ), onPressed: () { // Update the state i.e. toogle the state of passwordVisible variable setState(() { _passwordVisible = !_passwordVisible; }); }, ), ), );
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!
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; }); }, ),