TextInputLayout是一个可以把EditText包裹在当中的一个布局,当输入文字时,它能够把Hint文字飘到EditText的上方,错误信息显示在editText的下方。java
TextInputLayout用在登录注册的界面上很常见,作出来的效果也很炫,下面咱们就用TextInputLayout来建立一个登录界面
首先先把须要的包经过依赖添加到咱们的项目中android
dependencies { compile fileTree(dir: 'libs', include: ['*.jar']) compile 'com.android.support:design:22.2.0' compile 'com.android.support:appcompat-v7:22.2.0' }
UI很简单,一个Login的标签和两个EditText (用户名,密码框),不居中再加上一个登录按钮。
另外一个须要注意的细节是设置好两个输入框的inputType ,第一个框设置为textEmail ,第二个框设置为textPassword,布局以下所示。web
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<RelativeLayout android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="0.5"
android:orientation="vertical">
<TextView android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:gravity="center"
android:text="Login"
android:textSize="30sp"
android:textColor="#333333"/>
</RelativeLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:layout_weight="0.5">
<android.support.design.widget.TextInputLayout
android:id="@+id/text_input_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:hintTextAppearance="@style/hintStyle">
<android.support.design.widget.TextInputEditText
android:id="@+id/user_name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="textEmailAddress"
android:hint="Username"/>
</android.support.design.widget.TextInputLayout>
<android.support.design.widget.TextInputLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:hintTextAppearance="@style/hintStyle">
<android.support.design.widget.TextInputEditText
android:id="@+id/pass_word"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="textPassword"
android:hint="Password"/>
</android.support.design.widget.TextInputLayout>
<Button
android:id="@+id/confirm"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="确认"/>
</LinearLayout>
</LinearLayout>
<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
</style>
在setContentView()下面,初始化TextInputLayout 的引用。正则表达式
TextInputLayout username = (TextInputLayout) findViewById(R.id.text_user_layout); TextInputLayout password = (TextInputLayout) findViewById(R.id.text_pass_word_layout);
想要看到hint浮动的动画,还须要调用setHintapp
usernameWrapper.setHint("Username");
passwordWrapper.setHint("Password");
作完这个之后,这个应用已经彻底符合material design了,运行程序,而后你会看到登陆界面。
ide
TextInputLayout另外一个很赞的功能是,能够处理错误状况。经过验证用户输入,你能够防止用户输入错误的邮箱,或者输入不符合规则的密码。
有些输入验证,验证是在后台作得,产生错误后会反馈给前台,最后展现给用户。很是耗时并且用户体验差。最好的办法是在请求后台前作校验。svg
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// STUB
}
});
其实,当这个方法被调用之后,就不须要键盘了。可是不幸的是,Android不会自动隐藏。怎么办呢?调用下面的方法吧。布局
private void hideKeyboard() {
View view = getCurrentFocus();
if (view != null) {
((InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE)).
hideSoftInputFromWindow(view.getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS);
}
}
验证邮箱稍微有些复杂,咱们能够用Apache Commons library 来作这个事。我这里用一个维基百科里的正则表达式。动画
/^[a-zA-Z0-9#_~!&'()*+,;=:."(),:;<>@\[\]\\]+@[a-zA-Z0-9-]+(\.[a-zA-Z0-9-]+)*/
既然咱们想验证一个string,咱们必须依赖Pattern and Matcher,它们在java.util.regex下面。在Activity中导入它们。ui
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(String email) {
matcher = pattern.matcher(email);
return matcher.matches();
}
密码验证相对简单,不一样的组织有不一样的验证方式。可是大都有最小长度限制。最合理的规则就是至少输入六位字符。
public boolean validatePassword(String password) {
return password.length() > 5;
}
以前已说过,TextInputLayout只是一个容器。不像LinearLayout and ScrollView,你能够直接获取它的子元素经过特定的方法(getEditText)。根本木有必要使用findViewById。
若是TextInputLayout 中没有EditText,getEditText 会返回null,你得注意下NullPointException了。
public void onClick(View v) {
hideKeyboard();
String username = usernameWrapper.getEditText().getText().toString();
String password = usernameWrapper.getEditText().getText().toString();
// TODO: Checks
// TODO: Login
}
TextInputLayout 错误处理简单而迅速。相关的方法有setErrorEnabled和setError。
setError会弹出红色的提示消息同时显示在EditText下面,若是传入的错误消息是null,以前的消息会被清除掉。这个方法还会使EditText 也变红色。
setErrorEnabled 是控制这个功能的。这会直接影响layout的大小。
还有一个须要注意的是,若是没有调用setErrorEnabled(true)可是调用了setError 方法而且传入了非空的消息,setErrorEnabled(true) 会被自动调用。
正确和错误状况咱们已经说明了,下面就实现onClick 方法。
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
hideKeyboard();
String username = layout_name.getEditText().getText().toString();
String password = layout_name.getEditText().getText().toString();
if (!validateEmail(username)) {
layout_name.setError("邮箱格式有误!");
} else if (!validatePassword(password)) {
layout_password.setError("密码格式错误!");
} else {
layout_name.setErrorEnabled(false);
layout_password.setErrorEnabled(false);
doLogin();
}
}
});
下面是空的登陆方法:
public void doLogin() {
Toast.makeText(getApplicationContext(), "OK", Toast.LENGTH_SHORT).show();
}
修改TextInputLayout背景
<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
<item name="colorAccent">#3498db</item>
</style>
在TextInputLayout中配置
app:counterEnabled=”true”属性便可进行字数统计功能。
固然,你也能够指定最大输入的字符数,使用app:counterMaxLength=”15″属性
注意:在使用此属性时必须为TextInputLayout指定以下属性app:counterOverflowTextAppearance=”@style/MyOverflowText”
来改变文字超出时,提示文字的显示效果,不然程序将直接抛出异常,请注意,这是一个很大的坑,若是没有该属性的声明程序必定会报异常