Conteggio dei caratteri in tempo reale per EditText


102

Mi chiedevo quale sia il modo migliore per eseguire un conteggio dei caratteri in tempo reale di una casella di testo di modifica in Android. Stavo guardando questo ma non riuscivo a capirlo.

Per descrivere il problema, ho un EditText e sto cercando di limitare i caratteri a 150. Posso farlo con un filtro di input, tuttavia voglio mostrare proprio sotto la casella di testo il numero di caratteri che un utente ha inserito (Quasi come lo stack overflow sta facendo adesso).

Se qualcuno potesse scrivere un piccolo frammento di codice di esempio o indicarmi la giusta direzione, lo apprezzerei molto.

Risposte:


153

puoi usare un TextWatcher per vedere quando il testo è cambiato

private TextView mTextView;
private EditText mEditText;
private final TextWatcher mTextEditorWatcher = new TextWatcher() {
        public void beforeTextChanged(CharSequence s, int start, int count, int after) {
        }

        public void onTextChanged(CharSequence s, int start, int before, int count) {
           //This sets a textview to the current length
           mTextView.setText(String.valueOf(s.length()));
        }

        public void afterTextChanged(Editable s) {
        }
};

si imposta il TextWatcher per il testo editoriale con

mEditText.addTextChangedListener(mTextEditorWatcher);

5
provato questo, funziona alla grande! dovrebbe essere selezionato come risposta corretta!
Patrick Boos

2
quale sarebbe il modo migliore per aggiungere il conteggio diciamo in basso a destra nella casella di testo. Estendi il testo di modifica e disegna la stringa manualmente?
Bear

1
Grazie anche a me, ma come ottenere il conto alla rovescia in ordine inverso, ad esempio 150,149,148,147 ... durante l'inserimento del testo.
Vinay Maneti

6
Si è risolto sostituendo con questa riga mTextView.setText (String.valueOf (150-s.length ())); al posto di mTextView.setText (String.valueOf (s.length ()));
Vinay Maneti

Il mio problema è simile a quello di @Bear. Devo mostrare questo testo del conto alla rovescia proprio sotto il testo di modifica. Qualcuno ha qualcosa da condividere in questo riferimento. Grazie.
Suresh Sharma

108

Puoi eseguire il conteggio dei caratteri da xml stesso utilizzando il wrapper TextInputLayout per EditText introdotto in SupportLibrary v23.1

Basta racchiudere il tuo EditText con un TextInputLayout e impostare CounterEnabled su true e impostare un counterMaxLength.

<android.support.design.widget.TextInputLayout
    android:id="@+id/textContainer"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    app:counterEnabled="true"
    app:counterMaxLength="20"
    >
    <EditText
        android:id="@+id/text"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="Text Hint"
        />
</android.support.design.widget.TextInputLayout>

Otterrai un effetto materiale come questo

Puoi usare counterOverflowTextAppearance , counterTextAppearance per definire lo stile del contatore.

MODIFICARE

Dalla documentazione di Android.

La classe TextInputEditText viene fornita per essere utilizzata come figlio di questo layout. L'uso di TextInputEditText consente a TextInputLayout un maggiore controllo sugli aspetti visivi di qualsiasi input di testo. Un esempio di utilizzo è così:

     <android.support.design.widget.TextInputLayout
         android:layout_width="match_parent"
         android:layout_height="wrap_content">

     <android.support.design.widget.TextInputEditText
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
             android:hint="@string/form_username"/>

 </android.support.design.widget.TextInputLayout>

TextInputLayout TextInputEditText


3
questo era esattamente quello che stavo cercando :) una libreria di supporto pulita impl. grazie
VPZ

3
Dovrebbe essere la risposta accettata! Mi mancavano totalmente quegli attributi!
sud007

25

Puoi farlo con TextInputLayoute compatibilità librerie con:

app:counterEnabled="true"
app:counterMaxLength="420"

e completa:

<android.support.design.widget.TextInputLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    app:counterEnabled="true"
    app:counterMaxLength="420">

    <EditText
      android:layout_width="match_parent"
      android:layout_height="wrap_content"
      android:maxLength="420" />

</android.support.design.widget.TextInputLayout>

Ottimo questo ha funzionato per me, ma come cambio il colore del bancone?
Erich García

14

in xml aggiungi questo attributo per editText

    android:maxLength="80"

in java aggiungi questo listener

  ed_caption.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) {
            tv_counter.setText(80 - s.toString().length() + "/80");

        }
    });

7

È molto semplice Segui le istruzioni seguenti:

==== Aggiungili alle tue importazioni ===

import android.text.Editable;
import android.text.TextWatcher;

===== Definisci questo =====

private TextView sms_count;

========== Inside On Create =====

sms_count = (TextView) findViewById(R.id.textView2);


final TextWatcher txwatcher = new TextWatcher() {
   public void beforeTextChanged(CharSequence s, int start, int count, int after) {
   }

   public void onTextChanged(CharSequence s, int start, int before, int count) {

      sms_count.setText(String.valueOf(s.length()));
   }

   public void afterTextChanged(Editable s) {
   }
};

sms_message.addTextChangedListener(txwatcher);

5
    You can use TextWatcher class to see text has changed and how much number of character remains.Here i have set counter of 140 characters.

    EditText typeMessageToPost;
    TextView number_of_character;
public void onCreate(Bundle savedBundleInstance) {
        super.onCreate(savedBundleInstance);
setContentView(R.layout.post_activity);
typeMessageToPost.addTextChangedListener(mTextEditorWatcher);
}
private final TextWatcher mTextEditorWatcher=new TextWatcher() {

        @Override
        public void onTextChanged(CharSequence s, int start, int before, int count) {
            // TODO Auto-generated method stub

        }

        @Override
        public void beforeTextChanged(CharSequence s, int start, int count,
                int after) {
            // TODO Auto-generated method stub

        }

        @Override
        public void afterTextChanged(Editable s) {
            // TODO Auto-generated method stub
            number_of_character.setText(String.valueOf(140-s.length()));
        }
    };

Grazie @RavishSharma :) Apprezzo il tuo commento.
Rana Pratap Singh

4

Basta impostare queste 2 righe nel TextInputLayoutfile XML:

app:counterEnabled="true"
app:counterMaxLength="200"

Great non lo sapeva. Sembra sempre essere la soluzione migliore per racchiudere un Edittext in un TextInputLayout.
Stefan Sprenger

3

Questa soluzione utilizza Kotline mostra il numero di caratteri rimasti. Inoltre, se il numero corrente di caratteri supera il limite di 50, il colore del testo diventerà rosso.

Kotlin

private val mTitleTextWatcher = object : TextWatcher {
    override fun beforeTextChanged(s: CharSequence, start: Int, count: Int, after: Int) {}

    override fun onTextChanged(s: CharSequence, start: Int, before: Int, count: Int) {
        if(YOUR_EDIT_TEXT_ID.text.toString().trim().length < 51){
            YOUR_CHAR_LEFT_TEXTVIEW_ID.text = (50 - YOUR_EDIT_TEXT_ID.text.toString().trim().length).toString()
            YOUR_CHAR_LEFT_TEXTVIEW_ID.setTextColor(Color.BLACK)
        }
        else{
            YOUR_CHAR_LEFT_TEXTVIEW_ID.text = "0"
            YOUR_CHAR_LEFT_TEXTVIEW_ID.setTextColor(Color.RED)
        }
    }

    override fun afterTextChanged(s: Editable) {}
}

Inoltre, non dimenticare di aggiungere il file TextWatcheral tuoEditText

YOUR_EDIT_TEXT_ID.addTextChangedListener(mTitleTextWatcher)

3

Puoi aggiungere un contatore al tuo TextInputEditText che viene racchiuso in un TextInputLayout. Come puoi vedere nell'esempio, counterEnabledabilita questa funzione e ne counterMaxLenghdefinisce il numero di caratteri.

<com.google.android.material.textfield.TextInputLayout
        android:id="@+id/til_title"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:counterEnabled="true"
        app:counterMaxLength="50">
    <com.google.android.material.textfield.TextInputEditText
            android:id="@+id/et_title"
            android:layout_width="match_parent"
            android:layout_height="match_parent"/>
</com.google.android.material.textfield.TextInputLayout>

1

Ho incontrato lo stesso problema e ho provato il metodo di Cameron. Funziona ma c'è un bug minore: se l'utente usa copia e incolla, non riesce a contare i caratteri. Quindi suggerisco di fare dopo che il testo è cambiato, come di seguito:

    private final TextWatcher mTextEditorWatcher = new TextWatcher() {
         public void beforeTextChanged(CharSequence s, int start, int count, int after) {

         }

         public void onTextChanged(CharSequence s, int start, int before, int count) {

         }

          public void afterTextChanged(Editable s) {
             //This sets a textview to the current length
             mTextView.setText(String.valueOf(s.length()));
         }
    };


0

Prova a fare qualcosa di simile.

Questa soluzione potrebbe essere più performante rispetto a ottenere CharSequence.length. Ogni volta che si tocca sulla tastiera morbida l'evento si attiva; pertanto, se si esegue una lunghezza, verrà conteggiato ogni volta CharSequence, il che potrebbe rallentare se si inizia a entrare in CharSequnces di grandi dimensioni. L'ascoltatore di eventi al cambio di testo monta il conteggio del prima e del dopo. Funziona bene per i valori di incremento e decremento

@Override
        public void beforeTextChanged(CharSequence charSequence, int start, int count, int after) {
            int tick = start + after;
            if(tick < mMessageMax) {
                int remaining = mMessageMax - tick;
                ((TextView)findViewById(R.id.contact_us_chars)).setText(String.valueOf(remaining));
            }
        }

questo è un effetto permanente, TextWatcher è l'approccio migliore per questo
Naveed Ahmad

0

prova questo

private TextWatcher textWatcher = new TextWatcher() {
    @Override
    public void beforeTextChanged(final CharSequence s, final int start, final int count, final int after) {
        editText.post(new Runnable() {
            @Override
            public void run() {
                if (length < 100) {
                    if (count > 0 && after <= 0)/*remove emoij*/ {
                        length--;
                    } else if (count > after)/*remove text*/ {
                        length--;
                    } else if (count == 0 && after > 1)/*emoij*/ {
                        ++length;
                    } else if (count == 0 && after == 1)/*Text*/ {
                        ++length;
                    } else if (count > 0 && after > 1) {
                        ++length;
                    }
                    if (s.length() <= 0)
                        length = 0;
                    Log.w("MainActivity", " Length: " + length);
                } else {
                    if (count > 0 && after <= 0)/*remove emoij*/ {
                        length--;
                    } else if (count > after)/*remove text*/ {
                        length--;
                    }
                    Log.w("MainActivity", " Length: " + length);
                }

                if (length == 100) {
                    editText.setFilters(new InputFilter[]{new InputFilter.LengthFilter(s.length())});
                } else {
                    editText.setFilters(new InputFilter[]{});
                }
            }
        });
    }

    @Override
    public void onTextChanged(CharSequence s, int start, int before, int count) {

    }

    @Override
    public void afterTextChanged(Editable s) {

    }
};

"


0

Modo chiaro;

abstract class CharacterWatcher : TextWatcher {
    override fun afterTextChanged(text: Editable?) {
        afterCharacterChanged(text?.lastOrNull(), text?.length)
    }

    override fun beforeTextChanged(text: CharSequence?, start: Int, count: Int, before: Int) {}

    override fun onTextChanged(text: CharSequence?, start: Int, before: Int, count: Int) {}

    abstract fun afterCharacterChanged(char: Char?, count: Int?)
}



 editText.addTextChangedListener(new CharacterWatcher() {
            @Override
            public void afterCharacterChanged(@Nullable Character character, @Nullable Integer count) {
                action()
            }
        });
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.