Creating a Login Screen Using TextInputLayout

What You'll Be Creating

Introduction

In this tutorial, I will talk again about Material Design. Google I/O 2015 was an important event for every Android developer and design was of course part of the discussion.

Google has realized that backward compatibility is the trickiest part of the material design implementation. Sure, support libraries, such as appcompat-v4 and appcompat-v7, are part of the solution. However, Theme.AppCompat doesn’t implement every material item used in Google’s official applications. One of the features that is not present in the AppCompat theme is the possibility to position a floating label on top of an EditText widget. You can see what I mean in the below example.

Official Material Design TextInputLayout implementation

During Google I/O 2015, the Android team released a brand new support library, the Design Support Library. It comes in very handy for this kind of problem. This tutorial will show you how to use the new TextInputLayout widget that's included in the Design Support Library.

1. Implementing TextInputLayout

Step 1: Create a New Project

In Android Studio, choose New > New project from the File menu. Enter the required information to configure the project and create the project. In my example, I targeted the project to API 7, which is the minimum API level supported by the Design Support Library. By targeting such a low API level, your app will run on almost every Android device. I've named the main activity LoginActivity and its layout file activity_login.xml.

After setting up the project, remove in the main activity the onCreateOptionsMenu and onOptionsItemSelected method that are automatically generated by Android Studio. The login screen we're about to create doesn’t need a menu so it's fine to delete these methods. Remember also to delete the XML menu file that lives in the res/menu folder.

Step 2: Import the Support Libraries

To use the TextInputLayout widget, you have to import two libraries. The first one is appcompat-v7, which ensures that the material styles are backward compatible. The second one is the Design Support Library.

In your project's build.gradle file, add the following lines in the project's dependencies:

If Gradle doesn’t automatically ask you to synchronize your project, choose Make module 'app' from the Build menu or press F9. By doing so, the Android Studio build system will automatically fetch the necessary resources and you will be able to import any required classes.

Step 3: Design the User Interface

The user interface of this project is very simple. It shows a welcome label (which can be easily replaced by a logo if you have one) and two EditText elements, one for the username and one for the password. The layout also includes a button that triggers the login sequence. The background color is a nice, flat, light grey.

Another important detail worth remembering is the correct setting of the inputType attribute of the EditText elements. The inputType of the first EditText element should be set to textEmail while that of the second one should be set to textPassword. This is what the layout should look like.

You may also want to get rid of the app bar, previously known as the action bar, by editing the style.xml file as shown below.

Step 4: Using TextInputLayout

We have finally arrived at the most interesting part of this tutorial. A TextInputLayout widget behaves exactly as a LinearLayout does, it’s just a wrapper. TextInputLayout only accepts one child element, similar to a ScrollView. The child element needs to be an EditText element.

Note that I specified another parameter in the EditText item, a hint. As you already know, this attribute allows you to show a custom hint when there’s no content in the EditText. Once the user starts typing, the hint disappears. This isn't great, because they lose context of the information they are entering.

Thanks to TextInputLayout, this won’t be a problem anymore. While the EditText alone will hide the hint after the first character is typed, when wrapped in a TextInputLayout the hint will become a floating label above the EditText. A nice material animation is included too.

Next, let's do the same for the password field.

If you run the application now, nothing will happen. Sure, the EditText hint attribute will behave as expected. However, there's no material animation and no floating labels. Why is that? We're still missing some code to make everything work.

Step 5: Setting Hints

Below the setContentView method, initialize the references to the TextInputLayout views.

To animate the floating label, you just need to set a hint, using the setHint method.

And you’re done. Your login screen now properly follows the material design guidelines. Run the application to see your beautiful login screen.

Login Screen

2. Handling Errors

Another nice feature of TextInputLayout is the way it can handle errors. By validating the input, you prevent users from misspelling their email address or entering a password that is too short.

With input validation, incorrect credentials would be processed by the backend, errors would be generated and sent to the client, and shown to the (waiting) user. A considerable loss of time and a poor user experience. You should check the user's input before sending it to the backend.

Step 1: Implementing the onClick Method

You first have to handle the button click. There are plenty of ways to handle button clicks. One of them is by writing a custom method and specifying it in your XML file via the onClick attribute. I prefer setOnClickListener, but it’s really just a matter of personal taste.

We know that if this method is called, the user doesn’t need the keyboard anymore. Unfortunately, Android doesn't hide the virtual keyboard automatically, unless you tell it to. Call hideKeyboard in the onClick method body.

Step 2: Validating Input

Before setting the error labels, we need to define what's an error and what isn't. We're assuming that the username must be an email address and we want to prevent users from entering an invalid email address.

Validating an email address is a little bit complex. We have to rely on regular expressions. You can use the Apache Commons library too if you wish.

I've written the following regular expression, using the guidelines suggested by Wikipedia about email validity.

The meaning of this regular expression is quite simple. It's comprised of three capturing groups. The first one matches the letters of the alphabet (upper and lower case), numbers, and a series of accepted symbols. Because of the + quantifier, this group matches a string that’s composed of at least one character.

Next, there’s the @ symbol, which is of course required in every email address. The second group accepts only letters, numbers, and hyphens. The length also needs to be at least one (]+).

Finally, there's the last group, which contains a dot and whose purpose is matching subdomains and the TLD. Its quantifier is a star, *, which means that this group looks for a string whose length can be zero or more. In fact, email addresses with a domain, but no TLD, are actually valid.

Since we want to validate a String, we have to rely on Pattern and Matcher classes, included in the java.util.regex package. Import these classes in your activity and then implement the following method:

The validation of the password field is much simpler. Most organizations implement different policies for password validity, but everyone imposes a minimum length. A reasonable rule of thumb is that the password should never be shorter than six characters.

Step 3: Retrieving Data

As I said, TextInputLayout is just a wrapper, but unlike LinearLayout and ScrollView, you can get its child element using a specific method, getEditText. There's no need to use findViewById.

If TextInputLayout doesn't contain an EditTextgetEditText returns null so be careful of a NullPointException.

Step 4: Showing Errors

TextInputLayout error handling is easy and fast. The required methods are setErrorEnabled and setError.

setError sets a red error message that will be displayed below the EditText. If the parameter passed is null, the error message is cleared. It also changes the color of the whole EditText widget to red.

setErrorEnabled enables the error functionality. This directly affects the size of the layout, increasing the lower padding to make room for the error label. Enabling this functionality before setting an error message via setError means that this layout will not change size when an error is displayed. You should do some tests combining these two methods so that you actually see what I am talking about.

Another interesting fact is that if the error functionality has not been enabled yet and you call setError passing a non-null parameter, then setErrorEnabled(true) will be automatically called.

Now that we have defined what’s right and what’s wrong, and we know how to retrieve data  and display possible errors, the implementation of the onClick method becomes trivial.

I've added a doLogin method, but it's currently empty since this is beyond the scope of this tutorial.

3. Styling

You might want to do one last thing, changing the color of the TextInputLayout widget. By default, the AppCompact theme sets it to green, but quite often this color conflicts with your color palette.

Google wrote the Design Support Library very well. Every widget’s color is drawn directly from the theme’s colors, specified in your style.xml file. Just open it and add the colorAccent item to your active theme to change the form's color scheme.

Login Screen with a different color

Conclusion

In this tutorial, we saw how to implement the new layout item TextInputLayout, thanks to the just introduced Design Support Library. 

The design paradigm that this widget implements allows users to never never lose context of the information they are entering and it was actually introduced by Google last year, along with Material Design.

At that time, there was no support library giving developers the possibility to put this widget into action in their projects, until Google I/O 2015. Now, if your application expects some sort of data input, you will finally be truly material design compliant.

Tags:

Comments

Related Articles