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
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
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
Customizing "submit" Button with this frame layout (in drawable folder):