Building a clean Login UI in Flutter
In this article, we will be building a clean, minimalistic login page with hints of inspiration from Facebook’s login page.
I have been learning Flutter for a few months now, and what I absolutely love about Flutter is how fast you can make your apps come to life. Since a major part of Flutter is community support, I decided to start writing articles about my experiences with Flutter to help people. ❤️
I am gonna assume you have some knowledge of the basic widgets such as Rows, Columns, etc. If you are a complete newbie, I suggest you head over to the documentation page of Flutter, which is more than enough to get you started. 🙌🏼
So let’s start by creating a new Flutter app. Remove all the boiler code. Right now, I just have one stateful widget named LoginPage.
We are going to be building our UI inside this widget.
Now, let’s add an enum. This enum is gonna store the state of our form type: Login or Register. We also declare some variables to store the value of the inputs we are about to enter.
We then define some TextEditingControllers for all the TextFormFields we are about to define, along with a GlobalKey for our Form. This key helps us track the state of the form. After that, we define some helper functions, to switch the form type from Login to Register or vice-versa.
With all this out of the way, let’s start painting our UI to life.
We should always try to make a lean widget tree to avoid clutter and build costs.
If you don’t understand me right now, don’t worry, you will, when we start coding this out. 💡
Add the following code to your build method in the _LoginPageState class.
We use a ListView to handle smaller screen sizes so that it doesn’t overflow and instead gracefully scrolls up and down. We then add some padding and a SizedBox to provide some empty space. The Image.asset method allows us to display a picture (make sure you add your image file to your project and pubsec.yaml). We then display the title of our app.
Now comes the most important part of our code. The FORM. Remember, the formKey we defined? We pass the same variable to key parameter of our Form widget. This helps us reset the form anytime we change from Login to Register or vice-versa. We then define a Column as its child which has two lists of type widget as its children: usernameAndPassword and submitButtons. Let’s define these now.
Remember the enum we defined? We use that enum, to check the form type. If form type is of type Login, we render the Login page, which consists of two TextFormFields, else if form type is of type Register, we render the Register page which consists of three TextFormFields. The styling of all the fields is the same. We also use the validator property of the TextFormField to do some basic validation, like checking if the fields are empty.
You can probably guess what’s happening here. We check the form type and render some widgets accordingly. But there is one new thing we are doing here. We also call our moveToLogin and moveToRegister methods when we tap the Login and Sign Up buttons respectively. These methods help us change the form type accordingly. For instance, when we are on the Register page and click on Login, the moveToLogin method is called and the formType is now changed to FormType.Login. Since the formType is now of Login type, we render the Login components, in both of our widget lists.
This is the point I wanted to make initially. By defining all of our main widgets outside the build method, we only change the widgets that actually need to be changed when we call those helper methods, saving the app the trouble of rebuilding the entire widget tree since the entire build method is not being invoked anytime I change my form type. We should always rebuild only the widgets that actually need to be rebuilt and not the entire tree. This is always a performance booster. 🚀
So, that’s it, we have successfully built a Login UI in Flutter, in just a few minutes. See, how fast and easy that was? This is just a small example of how powerful Flutter can be.⚡️
I loved writing this blog. Please 👏🏼 if you liked this. See you guys in the next one!