Пример использования Android TextInputLayout

В этом учебнике мы подробно рассмотрим функции, которые предоставляет нам Android TextInputLayout. Android TextInputLayout – это компонент дизайна, поставляемый с библиотекой поддержки Material Design.

Android TextInputLayout

Android TexInputLayout расширяет LinearLayout. Основное назначение TextInputLayout – действовать как обертка для EditText (или его потомка) и включать анимацию плавающих подсказок. Правило запоминания: TextInputLayout должен оборачивать TextInputEditText вместо обычного EditText. Почему? TextInputEditText является подклассом EditText и предназначен для использования в качестве дочернего элемента TextInputLayout. Кроме того, использование EditText вместо этого вызовет предупреждение: EditText добавлен не как TextInputEditText. Пожалуйста, переключитесь на использование этого класса вместо. TextInputLayout предлагает гораздо больше возможностей, чем просто отображение плавающих подсказок.

Функции Android TextInputLayout

Некоторые из функций, которые мы рассмотрим в этом учебнике:

  1. Включение/выключение плавающих подсказок
  2. Включение/выключение анимации плавающих подсказок
  3. Отображение сообщений об ошибке
  4. Отображение счетчика символов
  5. Предупреждение пользователя, когда количество символов превышает предел
  6. Настройка внешнего вида текста для подсказки с плавающим эффектом, метки ошибки, счетчика символов
  7. Переключатель видимости пароля

Мы рассмотрим каждую из этих функций и реализуем их в проекте 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.journaldev.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.journaldev.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 содержит поля 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.journaldev.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.journaldev.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 изменяет цвет счетчика текста, подсказки текста и цвет индикатора, когда превышается количество символов.
  • Второе поле EditText делает то же самое, но также изменяет счетчик пользовательский цвет текста и пользовательский размер текста, когда превышается лимит.

Чтобы указать стиль, который нам нужен, когда счетчик символов превышает свой лимит, нам нужно использовать атрибут 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.journaldev.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>

Чтобы отобразить текст ошибки, нам нужно вызвать метод setError(String) на экземпляре TextInputLayout в нашем классе MainActivity.java, как показано ниже.

package com.journaldev.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);

            }
        });


    }
}

В приведенном выше коде мы добавляем TextChangedListener (который реализует TextWatcher) на каждый экземпляр TextInputEditText. Мы отображаем метку ошибки, когда текущее количество символов превышает максимальный предел счетчика. Чтобы очистить метку ошибки, мы устанавливаем значение внутри 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.journaldev.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

Ссылка: Официальная документация Android

Source:
https://www.digitalocean.com/community/tutorials/android-textinputlayout-example