Android Material Design系列之TextInputLayout

前言

TextInputLayout是一个能够把EditText包裹在当中的一个布局,当输入文字时,它可以把Hint文字飘到EditText的上方,错误信息显示在editText的下方。

使用

TextInputLayout用在登陆注册的界面上很常见,做出来的效果也很炫,下面我们就用TextInputLayout来创建一个登陆界面
首先先把需要的包通过依赖添加到我们的项目中

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界面

UI很简单,一个Login的标签和两个EditText (用户名,密码框),不居中再加上一个登陆按钮。
另一个需要注意的细节是设置好两个输入框的inputType ,第一个框设置为textEmail ,第二个框设置为textPassword,布局如下所示。

"1.0" encoding="utf-8"?>
"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">
    "match_parent"
                    android:layout_height="wrap_content"
                    android:layout_weight="0.5"
                    android:orientation="vertical">

        "match_parent"
                  android:layout_height="wrap_content"
                  android:layout_centerInParent="true"
                  android:gravity="center"
                  android:text="Login"
                  android:textSize="30sp"
                  android:textColor="#333333"/>

    
    "match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        android:layout_weight="0.5">
        "@+id/text_input_layout"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            app:hintTextAppearance="@style/hintStyle">

            "@+id/user_name"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:inputType="textEmailAddress"
                android:hint="Username"/>

        

        "match_parent"
            android:layout_height="wrap_content"
            app:hintTextAppearance="@style/hintStyle">

            "@+id/pass_word"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:inputType="textPassword"
                android:hint="Password"/>

        
        

去掉ActionBar

设置提示信息(hints)

在setContentView()下面,初始化TextInputLayout 的引用。

TextInputLayout username = (TextInputLayout) findViewById(R.id.text_user_layout);
TextInputLayout password = (TextInputLayout) findViewById(R.id.text_pass_word_layout);

想要看到hint浮动的动画,还需要调用setHint

usernameWrapper.setHint("Username");
passwordWrapper.setHint("Password");

做完这个以后,这个应用已经完全符合material design了,运行程序,然后你会看到登录界面。
Android Material Design系列之TextInputLayout_第1张图片

处理错误

TextInputLayout另一个很赞的功能是,可以处理错误情况。通过验证用户输入,你可以防止用户输入错误的邮箱,或者输入不符合规则的密码。
有些输入验证,验证是在后台做得,产生错误后会反馈给前台,最后展示给用户。非常耗时而且用户体验差。最好的办法是在请求后台前做校验。

实现onClick 方法

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中导入它们。

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背景

Android Material Design系列之TextInputLayout_第2张图片

字数统计功能

在TextInputLayout中配置
app:counterEnabled=”true”属性即可进行字数统计功能。
当然,你也可以指定最大输入的字符数,使用app:counterMaxLength=”15″属性

注意:在使用此属性时必须为TextInputLayout指定如下属性app:counterOverflowTextAppearance=”@style/MyOverflowText”

来改变文字超出时,提示文字的显示效果,否则程序将直接抛出异常,请注意,这是一个很大的坑,如果没有该属性的声明程序一定会报异常

Android Material Design系列之TextInputLayout_第3张图片

你可能感兴趣的:(Android,Material,Design)