Android Material Design Features: TextInputLayout and SnackBar example

    Google I/O 2015 event bring to Android developers alot of new features in designs. Google has released new support libaries, especially, Design Support Libary make incredible changes for Android application developers work. It comes in very handy for changing old widgets into new ones. For example, you can use Toolbar instead of ActionBar.
    In this tutorial will show you how to use the new TextInputLayout widget and SnackBar that's included in the Design Support Library.
    TextInputLayout is layout which wraps an EditText (or descendant) to show a floating label when the hint is hidden due to the user inputting text. Also supports showing an error like original EditText. Overview, it make our EditText prettier and smoothly.
    Snackbar provide lightweight feedback about an operation. It show a brief message at the bottom of the screen on mobile and lower left on larger devices. Snackbar appear above all other elements on screen and only one can be displayed at a time. They automatically disappear after a timeout or after user interaction elsewhere on the screen, particularly after interactions that summon a new surface or activity. Snackbar can be swiped off screen. It's interface look like Toast but more professional, it is a UI element used for user feedback. Generally used when instantaneous feedback is required from the user, after an action is performed!

Starting new project

    Launch Android studio and start a new project, min-sdk I use is 14 (min sdk which Design Support Libary supports is 7).
    We must add libaries dependency to local gradle file to build project. In this example, I use ButterKnife to bind/inject views so I put these line in app/build.gradle file:
dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    compile 'com.android.support:appcompat-v7:22.2.1'
    compile 'com.android.support:design:22.2.1'
    compile 'com.jakewharton:butterknife:7.0.1'
}
    First, in layout design (xml file), if we want to use SnackBar, we must set CoordinatorLayout as root layout. It act as a container and perform specific interactions between child views. Like shifting up of floating action button when an Android snackbar appears:
    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. So, it look like this:
    Finally, we have a complete layout for main activity:
When running app:

Coding for main activity

     In this example, user will enter some information to TextInputLayouts, we will check it's correct or not and show errors alert directly in EditText and notice by SnackBar too. In order to showing errors, we use setError (String msg) method of TextInputLayout class.
    Of course, after click "Submit" Button, checkInputLayout() was called:
 public void checkInputLayout() {
        if (!validateEmail(email.getEditText())) {
            email.setError("Invalid email");
            showSnackBar("Example email: abc@gmail.com");
        } else if (!validateField(name)) {
            name.setError("Please input your name");
            showSnackBar("Example name: Hong Thai");
        } else if (!validateField(country)) {
            country.setError("Please input your country");
            showSnackBar("Example country: Vietnam");
        } else if (!validateField(age)) {
            age.setError("Please input yout age");
            showSnackBar("Put number of your age now");
        } else {
            email.setError("");
            showSnackBar("Yes, you've completed all fields with correct information");
        }
    }
    Regular expression (Regex) was used to check valid email address from user input. With a regex string suggested by Wikipedia, we have check email method:
 private static final String EMAIL_PATTERN = "^[a-zA-Z0-9#_~!$&'()*+,;=:.\"(),:;<>@\\[\\]\\\\]+@[a-zA-Z0-9-]+(\\.[a-zA-Z0-9-]+)*$";
    private Pattern pattern = Pattern.compile(EMAIL_PATTERN);
    private Matcher matcher;

    public boolean validateEmail(EditText emailText) {
        matcher = pattern.matcher(emailText.getText().toString().trim());
        return matcher.matches();
    }
    The last step is build a SnackBar and show it from bottom screen, customize it's content and add a Button in the it. When click at this Button, a Toast has been shown. This process was declared by this code:
private void showSnackBar(String message) {
        Snackbar snackbar = Snackbar
                .make(coordiLayout, message, Snackbar.LENGTH_LONG)
                .setAction("OK", onSnackBarClickListener());

        snackbar.setActionTextColor(Color.GREEN);
        View snackbarView = snackbar.getView();
        snackbarView.setBackgroundColor(Color.DKGRAY);
        TextView textView = (TextView) snackbarView.findViewById(android.support.design.R.id.snackbar_text);
        textView.setTextColor(Color.YELLOW);
        snackbar.show();
    }

    private View.OnClickListener onSnackBarClickListener() {
        return new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Toast.makeText(MainActivity.this, "You clicked SnackBar Button", Toast.LENGTH_SHORT).show();
            }
        };
    }
    Finally, we have full code for running activity:
package info.devexchanges.textinput;

import android.graphics.Color;
import android.os.Bundle;
import android.support.design.widget.CoordinatorLayout;
import android.support.design.widget.Snackbar;
import android.support.design.widget.TextInputLayout;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

import butterknife.Bind;
import butterknife.ButterKnife;
import butterknife.OnClick;

public class MainActivity extends AppCompatActivity {

    private static final String EMAIL_PATTERN = "^[a-zA-Z0-9#_~!$&'()*+,;=:.\"(),:;<>@\\[\\]\\\\]+@[a-zA-Z0-9-]+(\\.[a-zA-Z0-9-]+)*$";
    private Pattern pattern = Pattern.compile(EMAIL_PATTERN);
    private Matcher matcher;

    @Bind(R.id.email_field)
    TextInputLayout email;

    @Bind(R.id.username_field)
    TextInputLayout name;

    @Bind(R.id.country_field)
    TextInputLayout country;

    @Bind(R.id.age_field)
    TextInputLayout age;

    @Bind(R.id.btn_submit)
    Button btnSubmit;

    @Bind(R.id.coordinatorLayout)
    CoordinatorLayout coordiLayout;

    @OnClick(R.id.btn_submit)
    public void submit(View view) {
        checkInputLayout();
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        ButterKnife.bind(this); // inject views in this activity
    }

    private void checkInputLayout() {
        if (!validateEmail(email.getEditText())) {
            email.setError("Invalid email");
            showSnackBar("Example email: abc@gmail.com");
        } else if (!validateField(name)) {
            name.setError("Please input your name");
            showSnackBar("Example name: Hong Thai");
        } else if (!validateField(country)) {
            country.setError("Please input your country");
            showSnackBar("Example country: Vietnam");
        } else if (!validateField(age)) {
            age.setError("Please input yout age");
            showSnackBar("Put number of your age now");
        } else {
            email.setError("");
            showSnackBar("Yes, you've completed all fields with correct information");
        }
    }

    private void showSnackBar(String message) {
        Snackbar snackbar = Snackbar
                .make(coordiLayout, message, Snackbar.LENGTH_LONG)
                .setAction("OK", onSnackBarClickListener());

        snackbar.setActionTextColor(Color.GREEN);
        View snackbarView = snackbar.getView();
        snackbarView.setBackgroundColor(Color.DKGRAY);
        TextView textView = (TextView) snackbarView.findViewById(android.support.design.R.id.snackbar_text);
        textView.setTextColor(Color.YELLOW);
        snackbar.show();
    }

    private View.OnClickListener onSnackBarClickListener() {
        return new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Toast.makeText(MainActivity.this, "You clicked SnackBar Button", Toast.LENGTH_SHORT).show();
            }
        };
    }

    public boolean validateEmail(EditText emailText) {
        matcher = pattern.matcher(emailText.getText().toString().trim());
        return matcher.matches();
    }

    public boolean validateField(TextInputLayout inputLayout) {
        if (inputLayout.getEditText().getText().toString().trim().equals("")) {
            return false;
        } else {
            inputLayout.setError("");
            return true;
        }
    }
}

Some necessary files

Strings resources for whole project:
Customizing "submit" Button with this frame layout (in drawable folder):

Running application


    In this tutorial, we saw how to implement the new 2 layout items TextInputLayout and SnackBar in Design Support Library. Moreover, I also use ButterKnife libray to inject views. Please see my previous post to learn how to use it and go to it's Home Page to deep understanding and approach more details.


Share


Previous post
« Prev Post
Next post
Next Post »