Esempio di TextInputLayout su Android

In questo tutorial, analizzeremo approfonditamente le funzionalità che Android TextInputLayout ci offre. Android TextInputLayout è un componente di design che viene fornito con la Material Design Support Library.

Android TextInputLayout

Android TexInputLayout estende LinearLayout. L’uso principale di un TextInputLayout è quello di fungere da wrapper per EditText (o suoi discendenti) e abilitare le animazioni di suggerimento fluttuante. Regola generale: TextInputLayout dovrebbe avvolgere TextInputEditText invece dell’EditText normale . Motivo? TextInputEditText è una sottoclasse di EditText ed è progettato per essere utilizzato come figlio di TextInputLayout. Inoltre, utilizzare un EditText invece di esso ci restituirebbe un avviso: EditText aggiunto non è un TextInputEditText. Si prega di passare all'utilizzo di quella classe invece. TextInputLayout offre molto di più rispetto alla semplice visualizzazione di etichette di suggerimento fluttuante.

Funzionalità di Android TextInputLayout

Alcune delle funzionalità che tratteremo in questo tutorial sono:

  1. Abilitazione/Disabilitazione dei suggerimenti fluttuanti
  2. Abilitazione/Disabilitazione dell’animazione dei suggerimenti fluttuanti
  3. Visualizzazione dei messaggi di errore
  4. Visualizzazione del contatore di caratteri
  5. Allarmare l’utente quando il conteggio dei caratteri supera il limite
  6. Personalizzazione dell’aspetto del testo per suggerimento fluttuante, etichetta di errore, contatore di caratteri
  7. Interruttore di visibilità della password

Esamineremo ciascuna di queste funzionalità e le implementeremo in un progetto di Android Studio.

Struttura del progetto di esempio Android TextInputLayout

Questa è un’applicazione a singola attività. Faremo tutto all’interno del layout, dell’attività e dei file styles.xml e colors.xml. Innanzitutto, aggiungere la dipendenza per la libreria di supporto al design all’interno del file build.gradle come mostrato di seguito.

compile 'com.android.support:design:25.3.1'

Abilitare/Disabilitare Suggerimenti Fluttuanti

I suggerimenti fluttuanti sono abilitati per impostazione predefinita in un TextInputLayout. Per disabilitarli è necessario aggiungere il seguente attributo all’interno del tag : app:hintEnabled="false". Il codice XML sottostante proviene dal layout activity_main.xml e ha tre campi 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>

Il terzo campo EditText ha la suggerimento fluttuante disattivato. Vediamo l’output del codice sopra:

Abilitare/Disabilitare l’animazione del suggerimento fluttuante

Simile alla funzione precedente, l’animazione del suggerimento fluttuante è abilitata per impostazione predefinita. Per disabilitarla, dobbiamo aggiungere il seguente attributo all’interno del tag TextInputLayout. app:hintAnimationEnabled="false" Il codice XML seguente proviene dal layout activity_main.xml e ha campi EditText per uno qualsiasi dei casi.

<?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>

L’output del codice sopra è mostrato di seguito. È interessante notare che il secondo campo EditText non anima il suggerimento fluttuante quando è in focus.

Styling del suggerimento TextAppearance

Per utilizzare un textColor e textSize personalizzati per gli indizi, viene utilizzato il seguente attributo: app:hintTextAppearance="@style/HintText". Lo stile HintText è scritto all’interno del file styles.xml come mostrato di seguito

<style name="HintText" parent="TextAppearance.Design.Hint">
        <item name="android:textSize">16sp</item>
        <item name="android:textColor">@color/colorPrimary</item>
    </style>

Il codice XML seguente è tratto dal layout activity_main.xml e contiene campi EditText per ciascuno dei casi (con/senza hintTextAppearance).

<?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>

L’output del codice precedente è mostrato di seguito.

Contatore di caratteri

Il contatore di caratteri è una funzionalità utilizzata da diverse applicazioni. (Ricordi il limite di caratteri di Twitter?). Imposta app:counterEnabled su true e app:counterMaxLength con il numero massimo di caratteri desiderato nel TextInputLayout. Il contatore di caratteri viene visualizzato per impostazione predefinita sotto l’EditText (in basso a destra) e al momento della stesura di questo tutorial, non c’è modo di cambiarne la posizione. Lo stile del contatore è simile a quello del testo dell’indizio. app:counterTextAppearance è l’attributo utilizzato questa volta. Abbiamo aggiunto il seguente stile all’interno del file styles.xml del nostro progetto.

<style name="CounterText" parent="TextAppearance.Design.Counter">
        <item name="android:textSize">16sp</item>
        <item name="android:textColor">@color/my_pink</item>
    </style>

Il codice XML seguente è tratto dal layout activity_main.xml e contiene campi EditText con un contatore di caratteri predefinito e uno personalizzato.

<?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>

L’output del codice sopra è fornito di seguito. Osserviamo attentamente l’output sopra.

  • Il primo campo EditText cambia il colore del contatore textColor, il suggerimento textColor e il colore dell’indicatore quando il conteggio dei caratteri viene superato.
  • Il secondo campo EditText fa lo stesso, ma cambia anche il colore del contatore textColor personalizzato e la dimensione del textSize personalizzata quando viene superato il limite.

Per specificare lo stile che ci serve quando il contatore dei caratteri supera il limite, dobbiamo usare l’attributo counterFlow che vedremo dopo.

Overflow del contatore dei caratteri

Come abbiamo visto sopra, quando il conteggio dei caratteri supera il limite definito, il testo del contatore utilizza gli attributi definiti in counterFlow. Se gli attributi non fossero presenti, si attaccherebbe a quelli predefiniti come abbiamo visto nell’output sopra. Dobbiamo utilizzare il seguente parametro app:counterOverflowTextAppearance. Lo stile per CounterOverflow è presente all’interno del file 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>

Aggiungi il seguente snippet di codice al layout precedente 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>

Eseguiamo nuovamente l’applicazione.

Etichetta di errore

Impostare app:errorEnabled su true ci consente di visualizzare un testo di errore in determinate condizioni sotto il nostro campo EditText. Per stilizzare il testo di errore, useremmo l’attributo app:errorTextAppearance e aggiungeremmo il seguente codice all’interno del nostro file styles.xml.

<style name="ErrorText" parent="TextAppearance.Design.Error">
        <item name="android:textSize">16sp</item>
        <item name="android:textColor">@color/my_black</item>
    </style>

Il codice XML qui sotto proviene dal layout activity_main.xml e contiene campi EditText per un’etichetta di errore predefinita e una personalizzata.

<?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>

Per visualizzare il testo di errore, dovremo chiamare il metodo setError(String) su un’istanza di TextInputLayout nella nostra classe MainActivity.java come mostrato di seguito.

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);

            }
        });


    }
}

Nel codice sopra, aggiungiamo un TextChangedListener (che implementa TextWatcher) su ogni istanza di TextInputEditText. Visualizziamo l’etichetta di errore quando il conteggio dei caratteri corrente supera il limite massimo del contatore. Per cancellare l’etichetta di errore impostiamo il valore all’interno di setError() come null. L’output che ci restituisce il codice sopra è: Nota: L’indicatore del campo di testo utilizza lo stesso colore dell’etichetta di errore. Sovrascrive il colore impostato da counterOverflow quindi ha la massima priorità.

Toggle visibilità della password

Impostando app:passwordToggleEnabled su true ti permette di mostrare/nascondere la password. Per cambiare il colore dell’icona usa app:passwordToggleTint. Il codice XML seguente è dal layout activity_main.xml e contiene campi EditText per un toggle visibilità della password (icona predefinita e con un tinta).

<?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>

Il risultato visualizzato dal codice sopra è: Nota: Possiamo utilizzare le nostre icone personalizzate dal toggle di visibilità della password utilizzando app:passwordToggleDrawable. Questo conclude questo tutorial. Abbiamo coperto tutte le principali funzionalità presenti in TextInputLayout. Puoi scaricare il Progetto di Esempio Android TextInputLayout dal link qui sotto. Include ciascun frammento di codice sopra.

Scarica Progetto Android TextInputLayout

Riferimento: Documentazione Ufficiale Android

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