文档结构  
翻译进度:已翻译     翻译赏金:0 元 (?)    ¥ 我要打赏

当需要用户输入时,我们使用EditText组件.当需要特定格式的输入时,我们能给用户提供一个提示(即hint).但是,一旦用户开始输入提示消失了.有时,这对用户造成了困绕,因为当他输入的时候他已经忘记提示的内容了.新的material design库中介绍了一种新的EditText:Floating Lable EditText,对于安卓开发者而言是一种救赎.他初次展示了一个提示,当用户输入时,提示变成了一个浮动的标签,正如他的名字所述一样.

第 1 段(可获 2 积分)

在这篇指南中,我们将讨论如何使用material design库实现安卓中带浮动标签的文本输入框.

如果你想得到全部的代码,请点击下面的链接,然后点击"Download Now"按钮.

Floating Lable EditText是通过在EditText外包裹一层android.support.design.widget.TextInputLayout布局实现的.TextInputLayout是一个专门用来包裹EditText并渲染出对应标签的组件,它所包裹的EditText有输入错误时,我们将使用它来展示这些错误.

第 2 段(可获 2 积分)

预备要求

  1. 在你的个人电脑(Unix或者Windows系统)安装了Android Studio。你可以在这里学习如何安装。
  2. 一台使用 Android Studio 配置的实时安卓设备(智能手机或平板)

创建一个新的工程并添加Material Design库

compile 'com.android.support:design:23.0.0'
  1.  找到File菜单栏,  依次打开File → New → New Project  然后在弹出的界面中填写你的应用名称
  2. 输入公司域名,这是用来标识你的应用程序包在世界上的唯一性。
  3. 选择项目存放位置和最小SDK,在下一个界面选择 空活动(Empty Activity)为我们将添加大部分代码在活动中。然后,点击下一步。
  4. 填写一个活动的名称。确保生成布局文件的选择框被选中,否则我们必须自己去建立它。然后,点击完成,我们将填写活动名称为 SignUpActivity,因为我们模仿的注册页面用于几乎所有的应用程序。这是最好的浮动文字编辑框的最好用例。
  5. 添加TextInputLayout支持在你的项目中。在你的app目录中的build.gradle文件中添加以下的依赖。
  6. Gradle将会配置您的项目和解析依赖关系。一旦完成,继续下一个步骤。

 

 

第 3 段(可获 2 积分)

我们使用安卓浮动文本编辑框构建一个模拟注册界面来作为例子。我们将会用TextInputLayout布局包裹的编辑框。在完成之后,这个布局将会如下图所示

添加布局

打开 activity_sign_up.xml   文件然后添加以下代码:

activity_sign_up.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:gravity="center"
    android:orientation="vertical"
    android:padding="10dp" >

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:orientation="vertical"
        android:paddingLeft="20dp"
        android:paddingRight="20dp" >
        <android.support.design.widget.TextInputLayout
            android:id="@+id/signup_input_layout_name"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_centerHorizontal="true"
            android:layout_marginTop="10dp">

            <EditText
                android:id="@+id/signup_input_name"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:ems="10"
                android:hint="Name"/>
        </android.support.design.widget.TextInputLayout>
        <android.support.design.widget.TextInputLayout
            android:id="@+id/signup_input_layout_email"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_centerHorizontal="true"
            android:layout_marginTop="10dp">
            <EditText
                android:id="@+id/signup_input_email"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:ems="10"
                android:inputType="textEmailAddress"
                android:hint="Email" />
        </android.support.design.widget.TextInputLayout>
        <android.support.design.widget.TextInputLayout
            android:id="@+id/signup_input_layout_password"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_centerHorizontal="true"
            android:layout_marginTop="10dp">
            <EditText
                android:id="@+id/signup_input_password"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:ems="10"
                android:inputType="textPassword"
                android:hint="@string/hint_password" />
        </android.support.design.widget.TextInputLayout>
        <android.support.design.widget.TextInputLayout
            android:id="@+id/signup_input_layout_dob"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_centerHorizontal="true"
            android:layout_marginTop="10dp">
            <EditText
                android:id="@+id/signup_input_dob"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:ems="10"
                android:singleLine="true"
                android:hint="@string/hint_dob"/>
        </android.support.design.widget.TextInputLayout>
        <RelativeLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:paddingTop="20dp">
            <TextView
                android:id="@+id/gender_textview"
                android:paddingRight="15dp"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="@string/hint_gender"
                android:fontFeatureSettings="@string/hint_password"
                android:textSize="20dp"
                android:fontFamily="@string/hint_password"/>
            <RadioGroup
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_toRightOf="@+id/gender_textview"
                android:orientation="horizontal"
                >
                <RadioButton
                    android:id="@+id/male_radio_btn"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:text="@string/male"
                    android:checked="true"
                    />
                <RadioButton
                    android:id="@+id/female_radio_btn"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:text = "@string/female"
                    />
            </RadioGroup>
        </RelativeLayout>
        <Button android:id="@+id/btn_signup"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:text="@string/btn_sign_up"
            android:background="@color/colorPrimaryDark"
            android:layout_marginTop="40dp"
            android:textColor="@android:color/white"/>
    </LinearLayout>
</LinearLayout>

 

 

 

 

第 4 段(可获 2 积分)

上面的布局是十分清晰,我们可以看到输入名字,邮件,密码和出生日期的编辑框( EditText ),还有一个用来获得性别输入的单选组件( RadioGroup )。这些都是用户在注册应用或者网站提交的常见信息。最后,我们还有一个用来提交的注册按钮(Button)。

添加功能

SignUpActivity.java  文件中,我们首先声明EditText和TextInputLayout类型的变量。

打开 SignUpActivity.java  文件,然后添加一下代码。

package com.androidtutorialpoint.floatinglabeledittext;

import android.content.Context;
import android.os.Bundle;
import android.os.Vibrator;
import android.support.design.widget.TextInputLayout;
import android.support.v7.app.AppCompatActivity;
import android.text.Editable;
import android.text.TextUtils;
import android.text.TextWatcher;
import android.view.View;
import android.view.WindowManager;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;


public class SignUpActivity extends AppCompatActivity {

    private static final String TAG = "RegisterActivity";
    private Vibrator vib;
    Animation animShake;
    private EditText signupInputName, signupInputEmail, signupInputPassword, signupInputDOB;
    private TextInputLayout signupInputLayoutName, signupInputLayoutEmail, 
                            signupInputLayoutPassword,signupInputLayoutDOB;
    private Button btnSignUp;
第 5 段(可获 2 积分)

现在我们在 SignUpActvity.java  文件中的 OnCreate()  方法中获取控件。

@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_sign_up);
        signupInputLayoutName = (TextInputLayout) findViewById(R.id.signup_input_layout_name);
        signupInputLayoutEmail = (TextInputLayout) findViewById(R.id.signup_input_layout_email);
        signupInputLayoutPassword = (TextInputLayout) findViewById(R.id.signup_input_layout_password);
        signupInputLayoutDOB = (TextInputLayout) findViewById(R.id.signup_input_layout_dob);

        signupInputName = (EditText) findViewById(R.id.signup_input_name);
        signupInputEmail = (EditText) findViewById(R.id.signup_input_email);
        signupInputPassword = (EditText) findViewById(R.id.signup_input_password);
        signupInputDOB = (EditText) findViewById(R.id.signup_input_dob);
        btnSignUp = (Button) findViewById(R.id.btn_signup);

        animShake = AnimationUtils.loadAnimation(getApplicationContext(),R.anim.shake);
        vib = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);

        btnSignUp.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                submitForm();
            }
        });
    }

注意,我们使用了输入非法内容事件时晃动文本框的动画提示。添加动画,首先要在values文件夹中创建一个 animation  资源文件然后添加以下代码: shake.xml.。

当有一个无效的输入事件时,文本框将会晃动同时手机将会振动来提示用户的错误使用。添加振动功能,需要在 AndroidManifest.xml  中添加以下许可权限。

 

第 6 段(可获 2 积分)

AndroidManifest.xml

<uses-permission android:name="android.permission.VIBRATE"></uses-permission>

OnClickListener (监听事件),我们会调用函数submitForm(),这个方法将在验证用户输入,如果发现无效数据,它会抛出一个错误。

SignUpActvity.java 文件中的 onCreate() 方法之后添加以下代码

SignUpActivity.java

private void submitForm() {

        if (!checkName()) {
            signupInputName.setAnimation(animShake);
            signupInputName.startAnimation(animShake);
            vib.vibrate(120);
            return;
       }
        if (!checkEmail()) {
            signupInputEmail.setAnimation(animShake);
            signupInputEmail.startAnimation(animShake);
            vib.vibrate(120);
            return;
        }
        if (!checkPassword()) {
            signupInputPassword.setAnimation(animShake);
            signupInputPassword.startAnimation(animShake);
            vib.vibrate(120);
            return;
        }
        if (!checkDOB()) {
            signupInputDOB.setAnimation(animShake);
            signupInputDOB.startAnimation(animShake);
            vib.vibrate(120);
            return;
        }
        signupInputLayoutName.setErrorEnabled(false);
        signupInputLayoutEmail.setErrorEnabled(false);
        signupInputLayoutPassword.setErrorEnabled(false);
        signupInputLayoutDOB.setErrorEnabled(false);
        Toast.makeText(getApplicationContext(), 
        "You are successfully Registered !!", Toast.LENGTH_SHORT).show();
    }

    private boolean checkName() {
        if (signupInputName.getText().toString().trim().isEmpty()) {

            signupInputLayoutName.setErrorEnabled(true);
            signupInputLayoutName.setError(getString(R.string.err_msg_name));
            signupInputName.setError(getString(R.string.err_msg_required));
            return false;
        }
        signupInputLayoutName.setErrorEnabled(false);
        return true;
    }

    private boolean checkEmail() {
        String email = signupInputEmail.getText().toString().trim();
        if (email.isEmpty() || !isValidEmail(email)) {

            signupInputLayoutEmail.setErrorEnabled(true);
            signupInputLayoutEmail.setError(getString(R.string.err_msg_email));
            signupInputEmail.setError(getString(R.string.err_msg_required));
            requestFocus(signupInputEmail);
            return false;
        }
        signupInputLayoutEmail.setErrorEnabled(false);
        return true;
    }

    private boolean checkPassword() {
        if (signupInputPassword.getText().toString().trim().isEmpty()) {

            signupInputLayoutPassword.setError(getString(R.string.err_msg_password));
            requestFocus(signupInputPassword);
            return false;
        }
            signupInputLayoutPassword.setErrorEnabled(false);
           return true;
    }

    private boolean checkDOB() {

        try {
            boolean isDateValid = false;
            String[] s = signupInputDOB.getText().toString().split("/");
            int date = Integer.parseInt(s[0]);
            int month = Integer.parseInt(s[1]);

            if (date < 32 && month < 13)
                isDateValid = true;

            if (signupInputDOB.getText().toString().trim().isEmpty() && isDateValid) {

                signupInputLayoutDOB.setError(getString(R.string.err_msg_dob));
                requestFocus(signupInputDOB);
                signupInputDOB.setError(getString(R.string.err_msg_required));

                return false;
            }
        }catch(Exception ex){
            signupInputLayoutDOB.setError(getString(R.string.err_msg_dob));
            requestFocus(signupInputDOB);
            return false;
        }

        signupInputDOB.setError(null);
        return true;
    }

    private static boolean isValidEmail(String email) {
        return !TextUtils.isEmpty(email) && 
        android.util.Patterns.EMAIL_ADDRESS.matcher(email).matches();
    }

    private void requestFocus(View view) {
        if (view.requestFocus()) {
            getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE);
        }
    }

  这个 submitForm()  方法使用了 checkName(), checkEmail(), checkPassword()checkDOB()四个辅助方法来检查名字,电子邮件,密码和出生日期的填写情况,同时检查电子邮件和出生日期的有效性。

 

 

第 7 段(可获 2 积分)

 让我们简单讨论一下这些方法。

  1. checkName() – 检查必填字段姓名是否填写,如果没有填写,那么在signupInputLayoutName组件上调用setErrorEnabled(true)方法通知这儿有错误,并且通过setError(getString(R.string.err_msg_name)) 方法为signupInputLayoutName组件设置错误提示。此外,我们也可以通过setError(getString(R.string.err_msg_required))EditText输入框设置错误提示。接下来,我们返回false值给submitForm()方法,他将会调用振动动画。
  2. checkEmail() – 这个方法和checkName()方法类似,但是他不仅调用了输入是否为空方法,还调用了isValidEmail()方法来检查输入的邮箱地址是否合法。
  3. checkPassword() – 这个方法和checkName()方法类似,它检查密码字段是否为空,如果为空,他将设置一个错误提示,并且返回false值.
  4. checkDOB() – 这个方法检查用户输入的生日是否合法。
第 8 段(可获 2 积分)

我们使用一下的字符串资源文件.

strings.xml

<resources>
    <string name="app_name">FloatingLabelEditText</string>
    <string name="hint_dob">Enter D.O.B (DD/MM/YYYY)</string>
    <string name="hint_password">Password</string>
    <string name="hint_gender">I am</string>
    <string name="male">Male</string>
    <string name="female">Female</string>
    <string name="btn_sign_up">Sign Up !!</string>
    <string name="err_msg_name">Please enter a Name</string>
    <string name="err_msg_required">Valid Input Required</string>
    <string name="err_msg_email">Please enter a Valid Email</string>
    <string name="err_msg_password">Enter a Password</string>
    <string name="err_msg_dob">Enter a valid D.O.B</string>
</resources>

现在运行这个app并且测试这些校验器是否运行成功.你必须使用不同的测试用例来测试邮件和生日校验是否正确.教程介绍了建立在material design设计风格上带浮动标签的输入框,希望你喜欢这篇教程.

第 9 段(可获 2 积分)

接下来做什么?

学会使用Floating Label Edit Text后,我们能测试更多的可用属性,并写出更优美的登录页和表单. 接下来我们制作一篇新的教程:将使用本篇教程中创建的登录页,与使用php和mysql的服务器进行交互.

敬请期待我们写出更多的教程...欢迎订阅我们的博客来获取更多的安卓最新技术教程.如果喜欢我们的教程,可以在FacebookTwitter关注我们.

打开下面的链接,点击"Download Now"(现在下载)按钮来下载例子中的代码:

这篇教程(Android Material Design : Working with Floating Label EditText)首次发布在此网站:Android Tutorial Point.

第 10 段(可获 2 积分)

文章评论