Nombre de caractères en direct pour EditText

102

Je me demandais quelle était la meilleure façon de faire un décompte de caractères en direct d'une zone d'édition de texte sous Android. Je regardais cela mais je n'arrivais pas à y donner un sens.

Pour décrire le problème, j'ai un EditText et j'essaie de limiter les caractères à 150. Je peux le faire avec un filtre d'entrée, mais je veux montrer juste en dessous de la zone de texte le nombre de caractères qu'un utilisateur a entré (Presque comme le fait le débordement de pile en ce moment).

Si quelqu'un pouvait écrire un petit extrait de code d'exemple ou me diriger dans la bonne direction, je l'apprécierais beaucoup.

Taylor Perkins
la source

Réponses:

153

vous pouvez utiliser un TextWatcher pour voir quand le texte a changé

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

vous définissez le TextWatcher pour l'edittext avec

mEditText.addTextChangedListener(mTextEditorWatcher);
Cameron Ketcham
la source
5
essayé ceci, fonctionne très bien! devrait être sélectionné comme bonne réponse!
Patrick Boos
2
quelle serait la meilleure façon d'ajouter le décompte en bas à droite de la zone de texte. Étendre le texte d'édition et dessiner la chaîne manuellement?
Ours le
1
Merci, je l'ai aussi, mais comment obtenir le compte à rebours dans l'ordre inverse comme 150,149,148,147 .... en entrant le texte.
vinay Maneti
6
Il a résolu en remplaçant par cette ligne mTextView.setText (String.valueOf (150-s.length ())); à la place de mTextView.setText (String.valueOf (s.length ()));
vinay Maneti
Mon problème est similaire à celui de @Bear. Je dois afficher ce compte à rebours juste en dessous du texte d'édition. N'importe qui a quelque chose à partager dans cette référence. Merci.
Suresh Sharma
108

Vous pouvez effectuer le comptage de caractères à partir du XML lui-même à l'aide de l' encapsuleur TextInputLayout pour EditText introduit dans SupportLibrary v23.1

Enveloppez simplement votre EditText avec un TextInputLayout et définissez CounterEnabled sur true et définissez 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>

Vous obtiendrez un effet matériel comme celui-ci

Vous pouvez utiliser counterOverflowTextAppearance , counterTextAppearance pour styliser le compteur.

ÉDITER

De la documentation Android.

La classe TextInputEditText est fournie pour être utilisée en tant qu'enfant de cette disposition. L'utilisation de TextInputEditText permet à TextInputLayout de mieux contrôler les aspects visuels de toute entrée de texte. Un exemple d'utilisation est le suivant:

     <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

Midhun Vijayakumar
la source
3
c'était exactement ce que je cherchais :) un impl de bibliothèque de support propre. merci
VPZ
3
Devrait être la réponse acceptée! J'ai totalement raté ces attributs!
sud007
25

Vous pouvez le faire avec des TextInputLayoutbibliothèques compatibles avec:

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

et terminer:

<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>
Daniel Gomez Rico
la source
Super cela a fonctionné pour moi, mais comment changer la couleur du comptoir?
Erich García
14

en xml, ajoutez cet attribut pour editText

    android:maxLength="80"

en java, ajoutez cet auditeur

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

        }
    });
Amal Kronz
la source
7

C'est très simple Suivez les instructions ci-dessous:

==== Ajoutez-les à vos importations ===

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

===== Définissez ceci =====

private TextView sms_count;

========== À l'intérieur lors de la création =====

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);
Depinder Bharti
la source
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()));
        }
    };
Rana Pratap Singh
la source
Merci @RavishSharma :) J'apprécie votre commentaire.
Rana Pratap Singh
4

Définissez simplement ces 2 lignes TextInputLayoutdans votre fichier XML:

app:counterEnabled="true"
app:counterMaxLength="200"
Mortezahosseini
la source
Great ne savait pas à ce sujet. Il semble toujours être la meilleure solution pour envelopper un Edittext dans un TextInputLayout.
Stefan Sprenger le
3

Cette solution utilise Kotlinet affiche le nombre de caractères restants. De plus, si le nombre actuel de caractères dépasse la limite de 50, la couleur du texte deviendra rouge.

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) {}
}

N'oubliez pas non plus d'ajouter le TextWatcherà votreEditText

YOUR_EDIT_TEXT_ID.addTextChangedListener(mTitleTextWatcher)
Grantespo
la source
3

Vous pouvez ajouter un compteur à votre TextInputEditText encapsulé dans un TextInputLayout. Comme vous pouvez le voir dans l'exemple, counterEnabledactive cette fonctionnalité et counterMaxLenghdéfinit le nombre de caractères pour elle.

<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>
Sathish
la source
2

J'ai rencontré le même problème et j'ai essayé la méthode de Cameron. Cela fonctionne mais il y a un bug mineur: si l'utilisateur utilise le copier-coller, il ne compte pas les caractères. Je suggère donc de faire après le changement de texte, comme ci-dessous:

    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()));
         }
    };
GilbertLee
la source
1

Utilisez Android: maxLength = "140"

Cela devrait fonctionner. :)

J'espère que cela pourra aider

Alireza Ghanbarinia
la source
0

Essayez de faire quelque chose comme ça.

Cette solution peut être plus performante que l'obtention de CharSequence.length. Chaque fois que vous appuyez sur le clavier virtuel, l'événement se déclenche; par conséquent, si vous faites une longueur, il comptera chaque fois la CharSequence, ce qui peut ralentir si vous commencez à entrer dans de grandes CharSequnces. L'écouteur d'événement sur le changement de texte vire au comptage avant et après. Cela fonctionne bien pour les valeurs d'incrémentation et de décrémentation

@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));
            }
        }
Victor J. Garcia
la source
ceci est effet permosrmatce, TextWatcher est la meilleure approche pour cela
Naveed Ahmad
0

essaye ça

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

    }
};

»

Nankai
la source
0

Voie claire;

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()
            }
        });
Café Mert Ceyhan
la source