Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / Mobile / Android

Android Material Design: Working with Floating Label EditText

4.00/5 (6 votes)
17 Jul 2016CPOL4 min read 23.9K  
Android Material Design: Working with Floating Label EditText

We all use EditText when we want user input. We can provide a hint to the user as to what to enter in a particular EditText. However, once the user starts typing, the hint is gone. Sometimes, this causes confusion to the app user when he forgets which field he was interacting with. However, to the rescue of the Android developers, Floating Label EditText was introduced with the material design library. It initially shows the label as a hint, but when user starts entering a value in the EditText, that hint turns into a floating label as the name suggests.

In this tutorial, we will discuss how to implement Android Floating Label EditText using the material design library.

The Floating Label EditText is implemented by wrapping an android.support.design.widget.TextInputLayout around the EditText. TextInputLayout is a widget which is used specifically to wrap an EditText and render floating labels. We also use its functions to show errors for the particular EditText it surrounds.

Pre-requisites

  1. Android Studio installed on your PC (Unix or Windows).
  2. A real time Android device (Smartphone or Tablet) configured with Android Studio.

Creating a New Project and Adding Material Design Library

compile 'com.android.support:design:23.0.0'
  1. Go to File → New → New Project and enter your Application Name.
  2. Enter Company Domain, this is used to uniquely identify your App’s package worldwide.
  3. Choose project location and minimum SDK and on the next screen choose Empty Activity, since we would be adding most of the code Ourselves. Then, Click on Next.
  4. Choose an Activity Name. Make sure Generate Layout File check box is selected, otherwise we have to generate it ourselves. Then, click on Finish. We have chosen the Activity Name as SignUpActivity, since we are mimicking the signup page in used in almost all the apps. This is the best use case for the Floating Label EditText.
  5. To add support for TextInputLayout to your project, add the following dependency in your App’s build.gradle file.
  6. Gradle will configure your project and resolve the dependencies. Once it is complete, proceed to the next steps.

We are creating a dummy signup page for this Android Floating Label EditText example. We will make use of EditTexts, each of which will be wrapped in a TextInputLayout. After completion, the layout will look as in the below figure.

Floating Label Edit Text Tutorial

Adding the Layout

Open activity_sign_up.xml and add the following code.

activity_sign_up.xml

XML
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:gravity="center"
    android:orientation="vertical"
    android:padding="10dp" >

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:orientation="vertical"
        android:paddingLeft="20dp"
        android:paddingRight="20dp" >
        <android.support.design.widget.TextInputLayout
            android:id="@+id/signup_input_layout_name"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_centerHorizontal="true"
            android:layout_marginTop="10dp">

            <EditText
                android:id="@+id/signup_input_name"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:ems="10"
                android:hint="Name"/>
        </android.support.design.widget.TextInputLayout>
        <android.support.design.widget.TextInputLayout
            android:id="@+id/signup_input_layout_email"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_centerHorizontal="true"
            android:layout_marginTop="10dp">
            <EditText
                android:id="@+id/signup_input_email"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:ems="10"
                android:inputType="textEmailAddress"
                android:hint="Email" />
        </android.support.design.widget.TextInputLayout>
        <android.support.design.widget.TextInputLayout
            android:id="@+id/signup_input_layout_password"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_centerHorizontal="true"
            android:layout_marginTop="10dp">
            <EditText
                android:id="@+id/signup_input_password"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:ems="10"
                android:inputType="textPassword"
                android:hint="@string/hint_password" />
        </android.support.design.widget.TextInputLayout>
        <android.support.design.widget.TextInputLayout
            android:id="@+id/signup_input_layout_dob"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_centerHorizontal="true"
            android:layout_marginTop="10dp">
            <EditText
                android:id="@+id/signup_input_dob"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:ems="10"
                android:singleLine="true"
                android:hint="@string/hint_dob"/>
        </android.support.design.widget.TextInputLayout>
        <RelativeLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:paddingTop="20dp">
            <TextView
                android:id="@+id/gender_textview"
                android:paddingRight="15dp"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="@string/hint_gender"
                android:fontFeatureSettings="@string/hint_password"
                android:textSize="20dp"
                android:fontFamily="@string/hint_password"/>
            <RadioGroup
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_toRightOf="@+id/gender_textview"
                android:orientation="horizontal"
                >
                <RadioButton
                    android:id="@+id/male_radio_btn"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:text="@string/male"
                    android:checked="true"
                    />
                <RadioButton
                    android:id="@+id/female_radio_btn"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:text = "@string/female"
                    />
            </RadioGroup>
        </RelativeLayout>
        <Button android:id="@+id/btn_signup"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:text="@string/btn_sign_up"
            android:background="@color/colorPrimaryDark"
            android:layout_marginTop="40dp"
            android:textColor="@android:color/white"/>
    </LinearLayout>
</LinearLayout>

The above layout is pretty self explanatory, we have EditText for Name, Email, Password and Date of Birth and then we have a RadioGroup for getting the input for gender. These are the typical inputs you will get from the user to register her on your app or website. At last, we have a Sign Up!! button that will be used to submit the button.

Adding the Functionality

In the SignUpActivity.java, we first declare variables for the EditText and TextInputLayout.

Open SignUpActivity.java and add the following code.

Java
package com.androidtutorialpoint.floatinglabeledittext;

import android.content.Context;
import android.os.Bundle;
import android.os.Vibrator;
import android.support.design.widget.TextInputLayout;
import android.support.v7.app.AppCompatActivity;
import android.text.Editable;
import android.text.TextUtils;
import android.text.TextWatcher;
import android.view.View;
import android.view.WindowManager;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;


public class SignUpActivity extends AppCompatActivity {

    private static final String TAG = "RegisterActivity";
    private Vibrator vib;
    Animation animShake;
    private EditText signupInputName, signupInputEmail, signupInputPassword, signupInputDOB;
    private TextInputLayout signupInputLayoutName, signupInputLayoutEmail, 
                            signupInputLayoutPassword,signupInputLayoutDOB;
    private Button btnSignUp;

Now we reference these Widgets in the OnCreate() method of the SignUpActvity.java.

Java
@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_sign_up);
        signupInputLayoutName = (TextInputLayout) findViewById(R.id.signup_input_layout_name);
        signupInputLayoutEmail = (TextInputLayout) findViewById(R.id.signup_input_layout_email);
        signupInputLayoutPassword = (TextInputLayout) findViewById(R.id.signup_input_layout_password);
        signupInputLayoutDOB = (TextInputLayout) findViewById(R.id.signup_input_layout_dob);

        signupInputName = (EditText) findViewById(R.id.signup_input_name);
        signupInputEmail = (EditText) findViewById(R.id.signup_input_email);
        signupInputPassword = (EditText) findViewById(R.id.signup_input_password);
        signupInputDOB = (EditText) findViewById(R.id.signup_input_dob);
        btnSignUp = (Button) findViewById(R.id.btn_signup);

        animShake = AnimationUtils.loadAnimation(getApplicationContext(),R.anim.shake);
        vib = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);

        btnSignUp.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                submitForm();
            }
        });
    }

Note that we have used the animation to shake the EditText in the case of any invalid input. To add animation, create an animation resource file in the values folder and add the following file:

shake.xml

XML
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
    android:interpolator="@android:anim/overshoot_interpolator"
    android:fillAfter="true">

    <translate
        android:startOffset="100"
        android:fromXDelta="0%p"
        android:toXDelta="5%p"
        android:duration="100" />

    <translate
        android:startOffset="150"
        android:fromXDelta="0%p"
        android:toXDelta="-10%p"
        android:duration="160" />


    <translate
        android:startOffset="260"
        android:fromXDelta="0%p"
        android:toXDelta="10%p"
        android:duration="170" />


    <translate
        android:startOffset="380"
        android:fromXDelta="0%p"
        android:toXDelta="-10%p"
        android:duration="180" />


    <translate
        android:startOffset="510"
        android:fromXDelta="0%p"
        android:toXDelta="5%p"
        android:duration="140" />

</set>

When there is an Invalid input, the EditText will shake and phone will vibrate to alert the user about the error. For adding the Vibrate functionality, add the following permission in AndroidManifest.xml.

AndroidManifest.xml

XML
<uses-permission android:name="android.permission.VIBRATE"></uses-permission>

In the OnClickListener, we are calling the function submitForm(), which will validate the user input and throw an error in if it finds invalid data.

Add the following code in the SignUpActvity.java after the onCreate() method.

SignUpActivity.java

Java
private void submitForm() {

        if (!checkName()) {
            signupInputName.setAnimation(animShake);
            signupInputName.startAnimation(animShake);
            vib.vibrate(120);
            return;
       }
        if (!checkEmail()) {
            signupInputEmail.setAnimation(animShake);
            signupInputEmail.startAnimation(animShake);
            vib.vibrate(120);
            return;
        }
        if (!checkPassword()) {
            signupInputPassword.setAnimation(animShake);
            signupInputPassword.startAnimation(animShake);
            vib.vibrate(120);
            return;
        }
        if (!checkDOB()) {
            signupInputDOB.setAnimation(animShake);
            signupInputDOB.startAnimation(animShake);
            vib.vibrate(120);
            return;
        }
        signupInputLayoutName.setErrorEnabled(false);
        signupInputLayoutEmail.setErrorEnabled(false);
        signupInputLayoutPassword.setErrorEnabled(false);
        signupInputLayoutDOB.setErrorEnabled(false);
        Toast.makeText(getApplicationContext(), 
        "You are successfully Registered !!", Toast.LENGTH_SHORT).show();
    }

    private boolean checkName() {
        if (signupInputName.getText().toString().trim().isEmpty()) {

            signupInputLayoutName.setErrorEnabled(true);
            signupInputLayoutName.setError(getString(R.string.err_msg_name));
            signupInputName.setError(getString(R.string.err_msg_required));
            return false;
        }
        signupInputLayoutName.setErrorEnabled(false);
        return true;
    }

    private boolean checkEmail() {
        String email = signupInputEmail.getText().toString().trim();
        if (email.isEmpty() || !isValidEmail(email)) {

            signupInputLayoutEmail.setErrorEnabled(true);
            signupInputLayoutEmail.setError(getString(R.string.err_msg_email));
            signupInputEmail.setError(getString(R.string.err_msg_required));
            requestFocus(signupInputEmail);
            return false;
        }
        signupInputLayoutEmail.setErrorEnabled(false);
        return true;
    }

    private boolean checkPassword() {
        if (signupInputPassword.getText().toString().trim().isEmpty()) {

            signupInputLayoutPassword.setError(getString(R.string.err_msg_password));
            requestFocus(signupInputPassword);
            return false;
        }
            signupInputLayoutPassword.setErrorEnabled(false);
           return true;
    }

    private boolean checkDOB() {

        try {
            boolean isDateValid = false;
            String[] s = signupInputDOB.getText().toString().split("/");
            int date = Integer.parseInt(s[0]);
            int month = Integer.parseInt(s[1]);

            if (date < 32 && month < 13)
                isDateValid = true;

            if (signupInputDOB.getText().toString().trim().isEmpty() && isDateValid) {

                signupInputLayoutDOB.setError(getString(R.string.err_msg_dob));
                requestFocus(signupInputDOB);
                signupInputDOB.setError(getString(R.string.err_msg_required));

                return false;
            }
        }catch(Exception ex){
            signupInputLayoutDOB.setError(getString(R.string.err_msg_dob));
            requestFocus(signupInputDOB);
            return false;
        }

        signupInputDOB.setError(null);
        return true;
    }

    private static boolean isValidEmail(String email) {
        return !TextUtils.isEmpty(email) && 
        android.util.Patterns.EMAIL_ADDRESS.matcher(email).matches();
    }

    private void requestFocus(View view) {
        if (view.requestFocus()) {
            getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE);
        }
    }

The submitForm() method uses helper methods checkName(), checkEmail(), checkPassword() and checkDOB() and checks for presence of name, email, password and D.O.B, It also checks whether the email and D.O.B entered are valid.

Let’s briefly discuss about these methods.

  1. checkName() – Checks whether the mandatory field name is present or not. Otherwise, it calls setErrorEnabled(true) on the signupInputLayoutName to notify there is an error and setError(getString(R.string.err_msg_name)) to set the error message for the signupInputLayoutName. Additionally, we are also setting the error for the EditText using setError(getString(R.string.err_msg_required)) method. Then, we are returning false to the submitForm() so that it invokes the shake animation.
  2. checkEmail() – This method is similar to checkName() method, it additionally calls the isValidEmail() to check whether the entered email is valid or not.
  3. checkPassword() – This method is also similar to checkName() method. It checks whether the Password field is left blank or not. In case it is blank, it will raise an error and return false.
  4. checkDOB() – This method checks whether the Date of Birth entered by the user is valid or not.

We have used the following string resources.

strings.xml

XML
<resources>
    <string name="app_name">FloatingLabelEditText</string>
    <string name="hint_dob">Enter D.O.B (DD/MM/YYYY)</string>
    <string name="hint_password">Password</string>
    <string name="hint_gender">I am</string>
    <string name="male">Male</string>
    <string name="female">Female</string>
    <string name="btn_sign_up">Sign Up !!</string>
    <string name="err_msg_name">Please enter a Name</string>
    <string name="err_msg_required">Valid Input Required</string>
    <string name="err_msg_email">Please enter a Valid Email</string>
    <string name="err_msg_password">Enter a Password</string>
    <string name="err_msg_dob">Enter a valid D.O.B</string>
</resources>

Now run the app and test whether all the validations are fired or not. You have to test different test cases for testing whether the email and D.O.B validations are proper or not. Hope you liked this material design floating label edit text example tutorial.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)