Android TextInputLayout示例

时间:2020-02-23 14:29:20  来源:igfitidea点击:

在本教程中,我们将深入研究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的样式

为了对提示使用自定义的textColortextSize,请使用以下属性: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"通过密码可见性切换使用我们自己的自定义图标。