Android TextInputLayout示例
在本教程中,我们将深入研究Android TextInputLayout提供的功能。
Android TextInputLayout是材料设计支持库随附的设计组件。
Android TextInputLayout
Android TexInputLayout扩展了LinearLayout。
TextInputLayout的主要用途是充当EditText(或者其后代)的包装,并启用浮动提示动画。
经验法则:TextInputLayout应该包装TextInputEditText而不是普通的EditText。
原因? TextInputEditText是EditText的子类,旨在用作TextInputLayout的子级。
此外,改用EditText会向我们发出警告:ʻAddEditText不是TextInputEditText。
请改用该类。
TextInputLayout提供的功能不仅仅显示浮动提示标签。
Android TextInputLayout功能
我们将在本教程中介绍的一些功能包括:
- 启用/禁用浮动提示
- 启用/禁用浮动提示动画
- 显示错误信息
- 显示字符计数器
- 字符数超过限制时警告用户
- 自定义浮动提示,错误标签,字符计数器的文本外观
- 密码可见性切换
我们将研究所有这些功能,并在Android Studio项目中实现它们。
Android TextInputLayout示例项目结构
这是一个活动应用程序。
我们将处理布局,活动以及" styles.xml"和" colors.xml"文件中的所有内容。
首先,在build.gradle文件中添加对设计支持库的依赖,如下所示。
compile 'com.android.support:design:25.3.1'
启用/禁用浮动提示
默认情况下,在TextInputLayout中启用浮动提示。
要禁用它,我们需要在标签内添加以下属性:ʻapp:hintEnabled =" false""。
下面的xml代码来自" activity_main.xml"布局,并具有三个EditText字段。
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="https://schemas.android.com/apk/res/android"
xmlns:app="https://schemas.android.com/apk/res-auto"
xmlns:tools="https://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
tools:context="com.theitroad.featuresoftextinputlayout.MainActivity">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<android.support.design.widget.TextInputEditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="@dimen/activity_horizontal_margin"
android:hint="TextInputEditText"
<android.support.design.widget.TextInputLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="@dimen/activity_horizontal_margin">
<android.support.design.widget.TextInputEditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Floating Hint Enabled Default"
</android.support.design.widget.TextInputLayout>
<android.support.design.widget.TextInputLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="@dimen/activity_horizontal_margin"
app:hintEnabled="false">
<android.support.design.widget.TextInputEditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Floating Hint Disabled"
</android.support.design.widget.TextInputLayout>
</LinearLayout>
</ScrollView>
第三个EditText字段禁用了浮动提示。
让我们看看上面的代码为我们提供的输出:
启用/禁用浮动提示动画
与以前的功能类似,默认情况下启用浮动提示动画。
要禁用它,我们需要在TextInputLayout标记内添加以下属性。
app:hintAnimationEnabled =" false""
下面的xml代码来自于" activity_main.xml"布局,并且在两种情况下均具有EditText字段。
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="https://schemas.android.com/apk/res/android"
xmlns:app="https://schemas.android.com/apk/res-auto"
xmlns:tools="https://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
tools:context="com.theitroad.featuresoftextinputlayout.MainActivity">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<android.support.design.widget.TextInputLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="@dimen/activity_horizontal_margin">
<android.support.design.widget.TextInputEditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Floating Hint Enabled Default"
</android.support.design.widget.TextInputLayout>
<android.support.design.widget.TextInputLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="@dimen/activity_horizontal_margin"
app:hintAnimationEnabled="false">
<android.support.design.widget.TextInputEditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Hint Animation Disabled"
</android.support.design.widget.TextInputLayout>
</LinearLayout>
</ScrollView>
值得一提的是,第二个EditText字段在聚焦时并未设置浮动提示的动画。
设置提示TextAppearance的样式
为了对提示使用自定义的textColor和textSize,请使用以下属性:app:hintTextAppearance =" @ style/HintText"HintText样式写在styles.xml内,如下所示
<style name="HintText" parent="TextAppearance.Design.Hint">
<item name="android:textSize">16sp</item>
<item name="android:textColor">@color/colorPrimary</item>
</style>
下面的xml代码来自" activity_main.xml"布局,并具有针对两种情况(带有/不带有hintTextAppearance)的EditText字段。
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="https://schemas.android.com/apk/res/android"
xmlns:app="https://schemas.android.com/apk/res-auto"
xmlns:tools="https://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
tools:context="com.theitroad.featuresoftextinputlayout.MainActivity">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<android.support.design.widget.TextInputLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="@dimen/activity_horizontal_margin">
<android.support.design.widget.TextInputEditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Floating Hint Enabled"
</android.support.design.widget.TextInputLayout>
<android.support.design.widget.TextInputLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="@dimen/activity_horizontal_margin"
app:hintTextAppearance="@style/HintText">
<android.support.design.widget.TextInputEditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Custom Hint TextAppearance"
</android.support.design.widget.TextInputLayout>
</LinearLayout>
</ScrollView>
以上代码的输出如下所示。
字符计数器
字符计数器是许多应用程序使用的功能。
(还记得Twitter字符限制吗?)。
将app:counterEnabled设置为true,并将app:counterMaxLength设置为您要在TextInputLayout中使用的最大字符数。
默认情况下,字符计数器显示在EditText(右下)下方,在编写本教程时,尚无法更改位置。
设置计数器的样式类似于设置提示文本的样式。
app:counterTextAppearance是这次使用的属性。
我们在项目的styles.xml文件中添加了以下样式。
<style name="CounterText" parent="TextAppearance.Design.Counter">
<item name="android:textSize">16sp</item>
<item name="android:textColor">@color/my_pink</item>
</style>
下面的xml代码来自" activity_main.xml"布局,并具有带有默认字符计数器和自定义字符计数器的EditText字段。
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="https://schemas.android.com/apk/res/android"
xmlns:app="https://schemas.android.com/apk/res-auto"
xmlns:tools="https://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
tools:context="com.theitroad.featuresoftextinputlayout.MainActivity">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<android.support.design.widget.TextInputLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="@dimen/activity_horizontal_margin"
app:counterEnabled="true"
app:counterMaxLength="5"
app:hintTextAppearance="@style/HintText">
<android.support.design.widget.TextInputEditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Character Counter Limit 10"
</android.support.design.widget.TextInputLayout>
<android.support.design.widget.TextInputLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="@dimen/activity_horizontal_margin"
app:counterEnabled="true"
app:counterMaxLength="5"
app:counterTextAppearance="@style/CounterText"
app:hintTextAppearance="@style/HintText">
<android.support.design.widget.TextInputEditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Character Counter Custom TextAppearance"
</android.support.design.widget.TextInputLayout>
</LinearLayout>
</ScrollView>
上面代码的输出如下。
让我们仔细观察上面的输出。
当超出字符数时,第一个EditText字段将更改其计数器textColor,提示textColor和指示器颜色。
第二个EditText字段执行相同的操作,但是,当超出限制时,它将更改计数器的自定义textColor和自定义textSize。
要指定字符计数器超出其限制时所需的样式,我们需要使用接下来将要看到的counterFlow属性。
字符计数器溢出
如上所示,当字符数超过定义的限制时,计数器文本将使用counterFlow中定义的属性。
如果不存在该属性,则将保留默认属性,如上面输出所示。
我们需要使用以下参数ʻapp:counterOverflowTextAppearance`
CountersOverflow`的样式存在于styles.xml中:
<style name="CounterOverFlow" parent="TextAppearance.Design.Counter.Overflow">
<item name="android:textSize">16sp</item>
<item name="android:textColor">@color/my_orange</item>
</style>
将以下代码片段添加到先前的" activity_main.xml"布局中:
<android.support.design.widget.TextInputLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="@dimen/activity_horizontal_margin"
app:counterEnabled="true"
app:counterMaxLength="5"
app:counterOverflowTextAppearance="@style/CounterOverFlow"
app:counterTextAppearance="@style/CounterText"
app:hintTextAppearance="@style/HintText">
<android.support.design.widget.TextInputEditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="CounterOverflow CustomTextAppearance"
</android.support.design.widget.TextInputLayout>
让我们再次运行该应用程序。
错误标签
将ʻapp:errorEnabled`设置为true允许我们在EditText字段下方的条件下显示错误文本。
要设置错误文本的样式,我们将使用属性" app:errorTextAppearance",并将以下代码添加到我们的" styles.xml"文件中。
<style name="ErrorText" parent="TextAppearance.Design.Error">
<item name="android:textSize">16sp</item>
<item name="android:textColor">@color/my_black</item>
</style>
下面的xml代码来自" activity_main.xml"布局,并具有用于默认错误标签和自定义标签的EditText字段。
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="https://schemas.android.com/apk/res/android"
xmlns:app="https://schemas.android.com/apk/res-auto"
xmlns:tools="https://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
tools:context="com.theitroad.featuresoftextinputlayout.MainActivity">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<android.support.design.widget.TextInputLayout
android:id="@+id/errorInputLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="@dimen/activity_horizontal_margin"
app:counterEnabled="true"
app:counterMaxLength="5"
app:counterOverflowTextAppearance="@style/CounterOverFlow"
app:counterTextAppearance="@style/CounterText"
app:errorEnabled="true"
app:hintTextAppearance="@style/HintText">
<android.support.design.widget.TextInputEditText
android:id="@+id/errorEditText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Default Error Label"
</android.support.design.widget.TextInputLayout>
<android.support.design.widget.TextInputLayout
android:id="@+id/customErrorInputLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="@dimen/activity_horizontal_margin"
app:counterEnabled="true"
app:counterMaxLength="5"
app:counterOverflowTextAppearance="@style/CounterOverFlow"
app:counterTextAppearance="@style/CounterText"
app:errorEnabled="true"
app:errorTextAppearance="@style/ErrorText"
app:hintTextAppearance="@style/HintText">
<android.support.design.widget.TextInputEditText
android:id="@+id/customErrorEditText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Custom Error Label"
</android.support.design.widget.TextInputLayout>
</LinearLayout>
</ScrollView>
要显示错误文本,我们必须在MainActivity.java类中的TextInputLayout实例上调用方法setError(String),如下所示。
package com.theitroad.featuresoftextinputlayout;
import android.support.design.widget.TextInputEditText;
import android.support.design.widget.TextInputLayout;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.text.Editable;
import android.text.TextWatcher;
public class MainActivity extends AppCompatActivity {
TextInputLayout errorInputLayout, customErrorInputLayout;
TextInputEditText errorEditText, customErrorEditText;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
errorEditText = (TextInputEditText) findViewById(R.id.errorEditText);
errorInputLayout = (TextInputLayout) findViewById(R.id.errorInputLayout);
customErrorEditText = (TextInputEditText) findViewById(R.id.customErrorEditText);
customErrorInputLayout = (TextInputLayout) findViewById(R.id.customErrorInputLayout);
errorEditText.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
@Override
public void afterTextChanged(Editable s) {
if (s.length() > errorInputLayout.getCounterMaxLength())
errorInputLayout.setError("Max character length is " + errorInputLayout.getCounterMaxLength());
else
errorInputLayout.setError(null);
}
});
customErrorEditText.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
@Override
public void afterTextChanged(Editable s) {
if (s.length() > customErrorInputLayout.getCounterMaxLength())
customErrorInputLayout.setError("Max character length is " + customErrorInputLayout.getCounterMaxLength());
else
customErrorInputLayout.setError(null);
}
});
}
}
在上面的代码中,我们在每个TextInputEditText实例上添加一个" TextChangedListener"(实现TextWatcher)。
当前字符数超过计数器最大限制时,我们将显示错误标签。
为了清除错误标签,我们将setError()中的值设置为null。
上面的代码给我们的输出是:
注意:文本字段的指示器使用与错误标签相同的颜色。
它会覆盖counterOverflow设置的颜色,因此具有最高优先级。
密码可见性切换
将ʻapp:passwordToggleEnabled设置为true可以显示/隐藏密码。 要更改图标颜色,请使用ʻapp:passwordToggleTint。
下面的xml代码来自于" activity_main.xml"布局,并具有用于密码可见性切换的EditText字段(默认图标,带有色调)
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="https://schemas.android.com/apk/res/android"
xmlns:app="https://schemas.android.com/apk/res-auto"
xmlns:tools="https://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
tools:context="com.theitroad.featuresoftextinputlayout.MainActivity">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<android.support.design.widget.TextInputLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="@dimen/activity_horizontal_margin"
app:counterEnabled="true"
app:counterMaxLength="5"
app:counterOverflowTextAppearance="@style/CounterOverFlow"
app:counterTextAppearance="@style/CounterText"
app:hintTextAppearance="@style/HintText"
app:passwordToggleEnabled="true">
<android.support.design.widget.TextInputEditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Password Visibility Toggle"
android:inputType="textPassword"
</android.support.design.widget.TextInputLayout>
<android.support.design.widget.TextInputLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="@dimen/activity_horizontal_margin"
app:counterEnabled="true"
app:counterMaxLength="5"
app:counterOverflowTextAppearance="@style/CounterOverFlow"
app:counterTextAppearance="@style/CounterText"
app:hintTextAppearance="@style/HintText"
app:passwordToggleEnabled="true"
app:passwordToggleTint="@color/my_orange">
<android.support.design.widget.TextInputEditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Password Visibility Toggle Tint"
android:inputType="textPassword"
</android.support.design.widget.TextInputLayout>
</LinearLayout>
</ScrollView>
注意:我们可以使用" app:passwordToggleDrawable"通过密码可见性切换使用我们自己的自定义图标。

