Comment utiliser la classe TextWatcher sous Android?

103

Quelqu'un peut -il me dire comment masquer le sous - chaîne dans EditTextou comment changer d' EditText entrée substring type de mot de passe ou remplacer par un autre caractère comme celui - ci 123xxxxxxxxx3455

 String contents = et1.getText().toString();
 et1.setText(contents.replace.substring(0, contents.length()-2),"*");

S'il vous plaît, dites-moi comment je peux utiliser la TextWatcherméthode sous Android.

Développeur Android
la source

Réponses:

174

Pour l'utilisation du TextWatcher...

et1.addTextChangedListener(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
    }
});
Dinesh Prajapati
la source
59
que faire avec ce TextWatcher? Fournissez plus de détails pour une meilleure compréhension.
Paresh Mayani
Dans la méthode qui est remplacée pour l'observateur de texte. vous pouvez masquer le texte que vous vouliez vraiment.
Dinesh Prajapati
2
mais je ne sais pas comment utiliser TextWatcher, pouvez-vous expliquer avec un petit exemple merci pour vos directives
Développeur Android
mettre ce code en java..dès que l'utilisateur tape le texte une de la méthode sera appelée ... selon le nom de la fonction.
Dinesh Prajapati
1
En fait, si c'est l'exigence, mieux vaut ne pas utiliser l'observateur de texte.il va en boucle infinie
Dinesh Prajapati
119

L' TextWatcherinterface dispose de 3 méthodes de rappel qui sont toutes appelées dans l'ordre suivant lorsqu'une modification est apportée au texte:

beforeTextChanged(CharSequence s, int start, int count, int after)

Appelé avant que les modifications aient été appliquées au texte.
Le sparamètre est le texte avant toute modification.
Le startparamètre est la position du début de la partie modifiée dans le texte.
Le countparamètre est la longueur de la pièce modifiée dans la sséquence depuis la startposition.
Et le afterparamètre est la longueur de la nouvelle séquence qui remplacera la partie de la sséquence de startà start+count.
Vous ne devez pas modifier le texte TextViewde cette méthode (en utilisant myTextView.setText(String newText)).

onTextChanged(CharSequence s, int start, int before, int count)

Similaire à la beforeTextChangedméthode mais appelée après la modification du texte.
Le sparamètre est le texte une fois les modifications appliquées.
Le startparamètre est le même que dans la beforeTextChangedméthode.
Le countparamètre est le afterparamètre de la méthode beforeTextChanged.
Et le beforeparamètre est le countparamètre de la méthode beforeTextChanged.
Vous ne devez pas modifier le texte TextViewde cette méthode (en utilisant myTextView.setText(String newText)).

afterTextChanged(Editable s)

Vous pouvez modifier le texte dans le à TextViewpartir de cette méthode.
/! \ Attention: Lorsque vous modifiez le texte dans TextView, le TextWatchersera de nouveau déclenché, commençant une boucle infinie. Vous devez alors ajouter comme une boolean _ignorepropriété qui empêche la boucle infinie.
Exemple:

new TextWatcher() {
        boolean _ignore = false; // indicates if the change was made by the TextWatcher itself.

        @Override
        public void afterTextChanged(Editable s) {
            if (_ignore)
                return;

            _ignore = true; // prevent infinite loop
            // Change your text here.
            // myTextView.setText(myNewText);
            _ignore = false; // release, so the TextWatcher start to listen again.
        }

        // Other methods...
    }

Résumé:

entrez la description de l'image ici


Une classe prête à l'emploi: TextViewListener

Personnellement, j'ai fait mon écouteur de texte personnalisé, ce qui me donne les 4 parties dans des chaînes séparées, ce qui est, pour moi, beaucoup plus intuitif à utiliser.

 /**
   * Text view listener which splits the update text event in four parts:
   * <ul>
   *     <li>The text placed <b>before</b> the updated part.</li>
   *     <li>The <b>old</b> text in the updated part.</li>
   *     <li>The <b>new</b> text in the updated part.</li>
   *     <li>The text placed <b>after</b> the updated part.</li>
   * </ul>
   * Created by Jeremy B.
   */

  public abstract class TextViewListener implements TextWatcher {
    /**
     * Unchanged sequence which is placed before the updated sequence.
     */
    private String _before;

    /**
     * Updated sequence before the update.
     */
    private String _old;

    /**
     * Updated sequence after the update.
     */
    private String _new;

    /**
     * Unchanged sequence which is placed after the updated sequence.
     */
    private String _after;

    /**
     * Indicates when changes are made from within the listener, should be omitted.
     */
    private boolean _ignore = false;

    @Override
    public void beforeTextChanged(CharSequence sequence, int start, int count, int after) {
        _before = sequence.subSequence(0,start).toString();
        _old = sequence.subSequence(start, start+count).toString();
        _after = sequence.subSequence(start+count, sequence.length()).toString();
    }

    @Override
    public void onTextChanged(CharSequence sequence, int start, int before, int count) {
        _new = sequence.subSequence(start, start+count).toString();
    }

    @Override
    public void afterTextChanged(Editable sequence) {
        if (_ignore)
            return;

        onTextChanged(_before, _old, _new, _after);
    }

    /**
     * Triggered method when the text in the text view has changed.
     * <br/>
     * You can apply changes to the text view from this method
     * with the condition to call {@link #startUpdates()} before any update,
     * and to call {@link #endUpdates()} after them.
     *
     * @param before Unchanged part of the text placed before the updated part.
     * @param old Old updated part of the text.
     * @param aNew New updated part of the text?
     * @param after Unchanged part of the text placed after the updated part.
     */
    protected abstract void onTextChanged(String before, String old, String aNew, String after);

    /**
     * Call this method when you start to update the text view, so it stops listening to it and then prevent an infinite loop.
     * @see #endUpdates()
     */
    protected void startUpdates(){
        _ignore = true;
    }

    /**
     * Call this method when you finished to update the text view in order to restart to listen to it.
     * @see #startUpdates()
     */
    protected void endUpdates(){
        _ignore = false;
    }
  }

Exemple:

myEditText.addTextChangedListener(new TextViewListener() {
        @Override
        protected void onTextChanged(String before, String old, String aNew, String after) {
           // intuitive usation of parametters
           String completeOldText = before + old + after;
           String completeNewText = before + aNew + after;

           // update TextView
            startUpdates(); // to prevent infinite loop.
            myEditText.setText(myNewText);
            endUpdates();
        }
}
Yairopro
la source
Le problème avec ce code est que le curseur ne reste pas là où il est censé être ou du moins c'est mon expérience.
jonasxd360
Est-ce textview qui appelle ces méthodes
Je suppose que oui
Yairopro
Correction d'un problème avec le curseur de cette façon: protected void onTextChanged (String before, String old, String aNew, String after, Editable sequence)
Eugene Strelnikov
49

Réponse supplémentaire

Voici un complément visuel aux autres réponses. Ma réponse plus complète avec le code et les explications est ici .

  • Rouge: texte sur le point d'être supprimé (remplacé)
  • Vert: texte qui vient d'être ajouté (remplaçant l'ancien texte rouge)

entrez la description de l'image ici

Suragch
la source
6

Utilisation de TextWatcher sous Android

Voici un exemple de code. Essayez d'utiliser la addTextChangedListenerméthode de TextView

addTextChangedListener(new TextWatcher() {

        BigDecimal previousValue;
        BigDecimal currentValue;

        @Override
        public void onTextChanged(CharSequence s, int start, int before, int
                count) {
            if (isFirstTimeChange) {
                return;
            }
            if (s.toString().length() > 0) {
                try {
                    currentValue = new BigDecimal(s.toString().replace(".", "").replace(',', '.'));
                } catch (Exception e) {
                    currentValue = new BigDecimal(0);
                }
            }
        }

        @Override
        public void beforeTextChanged(CharSequence s, int start, int count,
                int after) {
            if (isFirstTimeChange) {
                return;
            }
            if (s.toString().length() > 0) {
                try {
                    previousValue = new BigDecimal(s.toString().replace(".", "").replace(',', '.'));
                } catch (Exception e) {
                    previousValue = new BigDecimal(0);
                }
            }
        }

        @Override
        public void afterTextChanged(Editable editable) {
            if (isFirstTimeChange) {
                isFirstTimeChange = false;
                return;
            }
            if (currentValue != null && previousValue != null) {
                if ((currentValue.compareTo(previousValue) > 0)) {
                    //setBackgroundResource(R.color.devises_overview_color_green);
                    setBackgroundColor(flashOnColor);
                } else if ((currentValue.compareTo(previousValue) < 0)) {
                    //setBackgroundResource(R.color.devises_overview_color_red);

                    setBackgroundColor(flashOffColor);
                } else {
                    //setBackgroundColor(textColor);
                }
                handler.removeCallbacks(runnable);
                handler.postDelayed(runnable, 1000);
            }
        }
    });
Anandu
la source
5

Une perspective un peu plus large de la solution:

@Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View v = inflater.inflate(R.layout.yourlayout, container, false);
        View tv = v.findViewById(R.id.et1);
        ((TextView) tv).addTextChangedListener(new TextWatcher() {
            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {
                 SpannableString contentText = new SpannableString(((TextView) tv).getText());
                 String contents = Html.toHtml(contentText).toString();
            }

            @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
            }
        });
        return v;
    }

Cela fonctionne pour moi, je le fais ma première fois.

Berit Larsen
la source
5

Créez une sous-classe TextWatcher personnalisée:

public class CustomWatcher implements TextWatcher {

    private boolean mWasEdited = false;

    @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 (mWasEdited){

            mWasEdited = false;
            return;
        }

        // get entered value (if required)
        String enteredValue  = s.toString();

        String newValue = "new value";

        // don't get trap into infinite loop
        mWasEdited = true;
        // just replace entered value with whatever you want
        s.replace(0, s.length(), newValue);

    }
}

Définissez l'écouteur pour votre EditText:

mTargetEditText.addTextChangedListener(new CustomWatcher());
Denis
la source
C'est en fait une manière intelligente et légère de résoudre le problème! Merci!
FRR
2

Pour Kotlin, utilisez la fonction d' extension KTX : (Il utilise TextWatchercomme réponses précédentes)

yourEditText.doOnTextChanged { text, start, count, after -> 
        // action which will be invoked when the text is changing
    }


importer core-KTX:

implementation "androidx.core:core-ktx:1.2.0"
Francis
la source
1
    public class Test extends AppCompatActivity {

    EditText firstEditText;
    EditText secondEditText;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.test);
        firstEditText = (EditText)findViewById(R.id.firstEditText);
        secondEditText = (EditText)findViewById(R.id.secondEditText);

        firstEditText.addTextChangedListener(new EditTextListener());

    }

    private class EditTextListener implements 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) {
            secondEditText.setText(firstEditText.getText());
        }

        @Override
        public void afterTextChanged(Editable s) {
        }
    }
}
Ajay Shrestha
la source
1

si vous implémentez avec le dialogue edittext. utiliser comme ceci:. sa même utilisation à d'autres edittext.

dialog.getInputEditText().addTextChangedListener(new TextWatcher() {
    @Override
    public void beforeTextChanged(CharSequence charSequence, int start, int before, int count) {
    }

    @Override
    public void onTextChanged(CharSequence charSequence, int start, int before, int count) {
        if (start<2){
                dialog.getActionButton(DialogAction.POSITIVE).setEnabled(false);
            }else{
                double size =  Double.parseDouble(charSequence.toString());
                if (size > 0.000001 && size < 0.999999){
                    dialog.getActionButton(DialogAction.POSITIVE).setEnabled(true);
                }else{
                    ToastHelper.show(HistoryActivity.this, "Size must between 0.1 - 0.9");
                    dialog.getActionButton(DialogAction.POSITIVE).setEnabled(false);
                }

            }
    }

    @Override
    public void afterTextChanged(Editable editable) {

    }
});
Izzamed
la source
-2
editext1.addTextChangedListener(new TextWatcher() {

   @Override
    public void onTextChanged(CharSequence s, int start, int before,
    int count) {
     editext2.setText(new String(s.toString()));

          }

   @Override
     public void beforeTextChanged(CharSequence s, int start, int count,
      int after) {

         editext2.setText(new String(s.toString()));
        }

      @Override
          public void afterTextChanged(Editable s) {

          editext2.setText(new String(s.toString()));
      }

         });

Pour plus d'informations, cliquez ici http://androiddhina.blogspot.in/2015/05/android-textwatcher.html

Dhina k
la source