Android的TextInputLayout示例
在本教程中,我们将深入了解Android TextInputLayout提供的功能。Android TextInputLayout是一个带有Material Design支持库的设计组件。
安卓的文本输入布局
Android的TextInputLayout继承自LinearLayout。TextInputLayout的主要用途是作为EditText(或其子类)的包装器,并启用浮动提示动画。经验法则:TextInputLayout应该包装TextInputEditText而不是普通的EditText。原因是?TextInputEditText是EditText的子类,专门设计用作TextInputLayout的子控件。此外,使用EditText会发出警告:添加的EditText不是TextInputEditText,请改用该类。TextInputLayout不仅可以显示浮动提示标签,还提供了更多功能。
安卓的TextInputLayout功能
在这个教程中,我们将会介绍一些功能。
-
- 启用/禁用浮动提示
-
- 启用/禁用浮动提示动画
-
- 显示错误消息
-
- 显示字符计数器
-
- 当字符计数超过限制时提醒用户
-
- 自定义浮动提示、错误标签、字符计数器的文本外观
- 密码可见性切换
我们将会逐一研究这些特点,并在Android Studio项目中实现它们。
Android TextInputLayout示例项目结构。
这是一个单Activity应用程序。我们将在layout、activity和styles.xml以及colors.xml文件中完成所有的工作。首先,按照下面所示,在build.gradle文件中添加关于design support library的依赖。
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.Olivia.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.Olivia.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 字段获得焦点时,浮动提示不会有动画效果。
设置提示文本的外观
要为提示使用自定义的文本颜色和文本大小,可以使用以下属性:app:hintTextAppearance=”@style/HintText” 在styles.xml中按照下面的示例编写HintText样式。
<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.Olivia.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.Olivia.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>
以上代码的输出如下。让我们仔细观察上述输出。
- The first EditText field changes its counter textColor, hint textColor and the indicator color when the character count is exceeded.
- The second EditText field does the same but also, it changes the counter custom textColor and custom textSize when the limit exceeds.
当字符计数超过限制时,为了指定我们所需的样式,我们需要使用接下来将要看到的counterFlow属性。
字符计数器溢出
正如我们在上面所看到的,当字符数超过定义的限制时,计数器文本会使用在counterFlow中定义的属性。如果属性不存在,它将使用默认属性,就像我们在上面的输出中看到的那样。我们需要使用以下参数app:counterOverflowTextAppearance。CounterOverflow的样式在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.Olivia.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.Olivia.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实例上添加了一个实现了TextWatcher接口的TextChangedListener。当当前字符计数超过计数器的最大限制时,我们显示错误标签。为了清除错误标签,我们将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.Olivia.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。这结束了本教程。我们已经介绍了TextInputLayout中的所有主要功能。您可以通过下方链接下载Android TextInputLayout示例项目。它包含了以上每个代码片段。
下载 Android TextInputLayout 项目
参考资料:安卓官方文档