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"通过密码可见性切换使用我们自己的自定义图标。