Flutter: Toggle Password Visibility

Flutter Image

    You might have seen an eye button that toggles the password visibility in Signup or Login forms on various websites. This button is important since there are many criteria to be followed while setting a password, so we might need to see if our password matches the pattern. This feature is quite popular and can be added to Flutter App as well.

    Let's look at the final output first to have an idea about what we are going to build :

     

    Get Started

    We will be starting right from scratch. First, we are going to create a flutter project and remove all the boilerplate code from the main.dart file. We are not going to add a lot of things in this app. We'll just have a screen with a password field.
    So, here is my main.dart file : 

    import 'package:flutter/material.dart';
    import 'login.dart';
    
    void main() {
      runApp(MyApp());
    }
    
    class MyApp extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          home: LoginForm(),   // We'll be adding it in the next step
        );
      }
    }
    

    You will get two errors in this file and both will be fixed in next step. We will fix them by creating a new file (login.dart) which will contain LoginForm Widget code. You can ignore them for now.


    Adding Login Form

    In this step, we are going to create a login.dart file which will contain a Stateful Widget called LoginForm. This will be a simple widget and will just contain a Password Input Field and Toggle Button.

    Password Field has an argument called obsecureText that hides the password visibility if set to true. The default value is false 

    Let's start by creating a login.dart file first and adding the below code :

    import 'package:flutter/material.dart';
    
    class LoginForm extends StatefulWidget {
      @override
      _LoginFormState createState() => _LoginFormState();
    }
    
    class _LoginFormState extends State<LoginForm> {
      bool _isHidden = true;
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          backgroundColor: Theme.of(context).secondaryHeaderColor,
          body: Center(
            child: Padding(
              padding: const EdgeInsets.all(20.0),
              child: TextField(
                obscureText: _isHidden,
                decoration: InputDecoration(
                  hintText: 'Password',
                ),
              ),
            ),
          ),
        );
      }
    }
    

    In the above code, we have just created a TextField and set the obsecureText argument to _isHidden. _isHidden is boolean variable set to true by default.

     

    Adding Toggle Button

    Next, we are going to add the toggle button to change the visibility of the password. We can do this easily using the suffixIcon property in InputDecoration. This will add an icon at the end of the input field.

    import 'package:flutter/material.dart';
    
    class LoginForm extends StatefulWidget {
      @override
      _LoginFormState createState() => _LoginFormState();
    }
    
    class _LoginFormState extends State<LoginForm> {
      bool _isHidden = true;
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          backgroundColor: Theme.of(context).secondaryHeaderColor,
          body: Center(
            child: Padding(
              padding: const EdgeInsets.all(20.0),
              child: TextField(
                obscureText: _isHidden,
                decoration: InputDecoration(
                  hintText: 'Password',
                  suffixIcon: Icon(Icons.visibility),   // Add this line
                ),
              ),
            ),
          ),
        );
      }
    }
    

     

    Adding Gesture Detector

    In this step, we will make the icon clickable so that when user clicks on it, it hides or shows the password. This is where the real logic comes. We will be using a method to toggle the password visibility, i.e., changing the obsecureText from true to false and vice-versa easily.

    import 'package:flutter/material.dart';
    
    class LoginForm extends StatefulWidget {
      @override
      _LoginFormState createState() => _LoginFormState();
    }
    
    class _LoginFormState extends State<LoginForm> {
      bool _isHidden = true;
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          backgroundColor: Theme.of(context).secondaryHeaderColor,
          body: Center(
            child: Padding(
              padding: const EdgeInsets.all(20.0),
              child: TextField(
                obscureText: _isHidden,
                decoration: InputDecoration(
                  hintText: 'Password',
                  suffixIcon: GestureDetector(
                    onTap: _togglePasswordView,
                    child: Icon(Icons.visibility),
                  ),
                ),
              ),
            ),
          ),
        );
      }
    
      void _togglePasswordView() {
        setState(() {
          _isHidden = !_isHidden;
        });
      }
    }
    

    To make the icon clickable, we can use GestureDetector or InkWell. We have wrapped the Icon with GestureDetector which has an onTap property. onTap takes a method which will be called when the icon is tapped. Notice that we have defined a method below called _togglePasswordView(also passed to onTap) which calls the setState method. Within that. we have used a very popular logic for toggling a boolean value using the not(!) operator. Suppose, isHidden was first true, then when the method is called, it will be set to !true, i.e., false and vice-versa.

     

    Toggling the icon

    We are all set now. We just need to make one simple change, i.e., changing the password visibility icon according to the password text visibility. If the text is visible, we can show an icon to make the text invisible. If the text is hidden, we can show another icon to make it visible. For this we have two icons - visibility(eye) and visibility_off(slashed-eye).

    import 'package:flutter/material.dart';
    
    class LoginForm extends StatefulWidget {
      @override
      _LoginFormState createState() => _LoginFormState();
    }
    
    class _LoginFormState extends State<LoginForm> {
      bool _isHidden = true;
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          backgroundColor: Theme.of(context).secondaryHeaderColor,
          body: Center(
            child: Padding(
              padding: const EdgeInsets.all(20.0),
              child: TextField(
                obscureText: _isHidden,
                decoration: InputDecoration(
                  hintText: 'Password',
                  suffixIcon: GestureDetector(
                    onTap: _togglePasswordView,
                    child: Icon(
                      _isHidden ? Icons.visibility : Icons.visibility_off, // Add this line
                    ),
                  ),
                ),
              ),
            ),
          ),
        );
      }
    
      void _togglePasswordView() {
        setState(() {
          _isHidden = !_isHidden;
        });
      }
    }
    

     We have used conditional operator to check if _isHidden is true, i.e., password is visible, then we would to like to show the visibility icon to hide the password else visibility_off will be used to show the password.

     

    Conclusion

    I hope all the above steps were clear and easy to understand for a beginner as well. Hope you liked the post. 
    Thanks!

    0 Comments

    To add a comment, please Signup or Login