1. 引言:
TextInputLayout也是作为一个控件容器,和LinearLayout完全一样。
它是Material Design的一部分,在Google I/O 2015期间,安卓团队发布了一个崭新的兼容库,Design Support Library。它是向后兼容实现material design的重要部分。而我们今天的主角:Design Support Library中的TextInputLayout控件,提供一个显示在EditText上方的浮动标签。一个单一的EditText 在输入文字的时候会隐藏hint,而被包含在TextInputLayout中的EditText则会让hint变成一个在EditText上方的浮动标签。同时还包括一个漂亮的material动画。
2. 实现
1. 导入Support Library
> 要使用TextInputLayout控件,你需要导入两个Library。第一个是appcompat-v7,它确保material style可以向后兼容。第二个是Design Support Library。在你的build.gradle文件中,添加如下依赖:
```
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile 'com.android.support:design:22.2.0'
compile 'com.android.support:appcompat-v7:22.2.0'
}
```
2. 使用TextInputLayout
跟ScrollView一样,TextInputLayout只接受一个子元素。子元素需要是一个EditText元素。
```
<android.support.design.widget.TextInputLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="5dp">
<EditText
android:id="@+id/login_et_user"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="用户名"
android:textSize="15sp" />
</android.support.design.widget.TextInputLayout>
```
```
<android.support.design.widget.TextInputLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="5dp">
<EditText
android:id="@+id/login_et_pwd"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="密码"
android:inputType="textPassword"
android:textSize="15sp" />
</android.support.design.widget.TextInputLayout>
```
3. 设置 Hints
注意上面的代码中的一个参数,hint。就如你知道的,这个属性允许你在EditText的内容为空的时候显示一个自定义的提示。一旦用户开始输入,hint会消失。这并没有很好的效果,因为用户丢失了他们输入信息的上下文提示。
此时我们可以通过设置hints的方式来让标签浮动到edittext上面
首先:
①初始化对TextInputLayout视图的引用
```
final TextInputLayout username = (TextInputLayout) findViewById(R.id.login_et_user);
final TextInputLayout password = (TextInputLayout) findViewById(R.id.login_et_pwd);
```
②设定setHint方法:
```
username.setHint("用户名");
password.setHint("密码");
```
此时的效果就已经出来了,
3.TextInputLayout还有另外的用处
此外,TextInputLayout还有另外的用处,那就是实现验证输入的功能。
这样可以防止用户输入无效的邮箱地址或者是太短的密码。
如果没有验证,后台可能反馈回不正确的结果呈现给用户。对于用户来说既浪费了时间又体验不好。
实现onClick方法:
btn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { // STUB //hideKeyboard(); } });
此处需要注意,Android不会自动的隐藏虚拟键盘,所以需要额外的在onClick中调用方法去隐藏keyboard。方法具体实现如下:
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-]+)*$/
因为我们想验证字符串,我必须依赖Pattern和Matcher两个类。includeava.util.regex 包。实现如下的方法:
``` 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(); } ```
密码验证相对简单:比如说合理的密码应该不低于6个字符。
```
public boolean validatePassword(String password) {
return password.length() > 5;
}
```
获取数据
可以使用一个特殊的方法获得子元素,getEditText,不需要使用findViewById。
所以onClick方法的呈现应该是这样的:``` public void onClick(View v) { hideKeyboard(); String username = username.getEditText().getText().toString(); String password = password.getEditText().getText().toString(); // TODO: Checks // TODO: Login } ```
显示错误
TextInputLayout的错误处理简单快速。需要的方法是setErrorEnabled和setError。setError设置一个红色的错误消息,显示在EditText的下面。如果传入的参数为null,错误消息将清空。并且它会改变整个EditText控件为红色。
setErrorEnabled开启错误提醒功能。这直接影响到布局的大小,增加底部padding为错误标签让出空间。在setError设置错误消息之前开启这个功能意味着在显示错误的时候布局不会变化。你可以把这两个方法结合起来验证下我所说的。
另一个有趣的事实是如果错误功能未开启但是你调用了传入非null参数的setError,那么setErrorEnabled(true)将自动被调用。
所以onClick此时的呈现:``` public void onClick(View v) { hideKeyboard(); String username = usernameWrapper.getEditText().getText().toString(); String password = usernameWrapper.getEditText().getText().toString(); if (!validateEmail(username)) { usernameWrapper.setError("Not a valid email address!"); } else if (!validatePassword(password)) { passwordWrapper.setError("Not a valid password!"); } else { usernameWrapper.setErrorEnabled(false); passwordWrapper.setErrorEnabled(false); doLogin();// TODO: Login } } ```
4.改变TextInputLayout控件的颜色
默认AppCompact会把它设置成绿色的,但是很有可能这个颜色会和你的颜色主题(color palette)冲突。
谷歌把Design Support Library写的很好。每一个控件的颜色都是直接通过主题颜色绘制的,在 style.xml 中指定。打开它添加colorAccent 到主题以改变表单的颜色。
```
<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
<item name="colorAccent">#3498db</item>
</style>
```
实现效果:
5.总结:
设计范例中,控件的实现需要让用户在输入的过程中不会丢失上下文信息,
我们借助了刚刚引入的Design Support Library,使用了新的布局元素TextInputLayout,来达到了这个目的。