Wie verwende ich die TextWatcher-Klasse in Android?

103

Kann mir jemand sagen , wie das maskieren String in EditTextoder wie sich ändern , EditText um Kennworttyp Teilzeicheneingabe oder ersetzen durch einen anderen Charakter wie diese 123xxxxxxxxx3455

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

Bitte sagen Sie mir, wie ich die TextWatcherMethode in Android verwenden kann.

Android-Entwickler
quelle

Antworten:

173

Zur Verwendung der 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
quelle
59
Was tun mit diesem TextWatcher? Geben Sie mehr Details zum besseren Verständnis an.
Paresh Mayani
In der Methode, die für den Text Watcher überschrieben werden. Sie können den Text maskieren, den Sie wirklich wollten.
Dinesh Prajapati
2
Aber ich weiß nicht, wie man TextWatcher benutzt. Kannst du es mit einem kleinen Beispiel erklären? Danke für deine Richtlinien
Android-Entwickler
Fügen Sie diesen Code in Java ein. Sobald der Benutzer den Text eingibt, wird eine der Methoden aufgerufen ... entsprechend dem Namen der Funktion.
Dinesh Prajapati
1
Wenn dies die Voraussetzung ist, ist es besser, den Text Watcher nicht zu verwenden. Es wird eine Endlosschleife geben
Dinesh Prajapati
119

Die TextWatcherSchnittstelle verfügt über 3 Rückrufmethoden, die alle in der folgenden Reihenfolge aufgerufen werden, wenn eine Änderung am Text vorgenommen wurde:

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

Wird aufgerufen, bevor die Änderungen auf den Text angewendet wurden.
Der sParameter ist der Text, bevor eine Änderung angewendet wird.
Der startParameter ist die Position des Anfangs des geänderten Teils im Text.
Der countParameter ist die Länge des geänderten Teils in der sSequenz seit der startPosition.
Und der afterParameter ist die Länge der neuen Sequenz, die den Teil der sSequenz von startbis ersetzt start+count.
Sie dürfen den Text in TextViewdieser Methode nicht ändern (mithilfe von myTextView.setText(String newText)).

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

Ähnlich der beforeTextChangedMethode, jedoch aufgerufen, nachdem sich der Text geändert hat.
Der sParameter ist der Text, nachdem Änderungen übernommen wurden.
Der startParameter ist der gleiche wie in der beforeTextChangedMethode.
Der countParameter ist der afterParameter in der beforeTextChanged-Methode.
Und der beforeParameter ist der countParameter in der beforeTextChanged-Methode.
Sie dürfen den Text in TextViewdieser Methode nicht ändern (mithilfe von myTextView.setText(String newText)).

afterTextChanged(Editable s)

Sie können den Text in TextViewdieser Methode ändern .
/! \ Warnung: Wenn Sie den Text in ändern TextView, TextWatcherwird der erneut ausgelöst und eine Endlosschleife gestartet. Sie sollten dann wie eine boolean _ignoreEigenschaft hinzufügen, die die Endlosschleife verhindert.
Beispiel:

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...
    }

Zusammenfassung:

Geben Sie hier die Bildbeschreibung ein


Eine gebrauchsfertige Klasse: TextViewListener

Persönlich habe ich meinen benutzerdefinierten Text-Listener erstellt, der mir die 4 Teile in separaten Zeichenfolgen gibt, was für mich viel intuitiver zu bedienen ist.

 /**
   * 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;
    }
  }

Beispiel:

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
quelle
Das Problem mit diesem Code ist, dass der Cursor nicht dort bleibt, wo er sein soll, oder zumindest war das meine Erfahrung.
Jonasxd360
Ist es Textansicht, die diese Methoden
Ich nehme an
Yairopro
Problem mit Cursor auf diese Weise behoben: protected void onTextChanged (Zeichenfolge vor, Zeichenfolge alt, Zeichenfolge neu, Zeichenfolge nach, bearbeitbare Sequenz)
Eugene Strelnikov
49

Ergänzende Antwort

Hier ist eine visuelle Ergänzung zu den anderen Antworten. Meine ausführlichere Antwort mit dem Code und den Erklärungen ist hier .

  • Rot: Text, der gelöscht werden soll (ersetzt)
  • Grün: Text, der gerade hinzugefügt wurde (ersetzt den alten roten Text)

Geben Sie hier die Bildbeschreibung ein

Suragch
quelle
6

Verwenden von TextWatcher in Android

Hier ist ein Beispielcode. Versuchen Sie es mit der addTextChangedListenerMethode von 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
quelle
5

Eine etwas größere Perspektive der Lösung:

@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;
    }

Das funktioniert bei mir, wenn ich es zum ersten Mal mache.

Berit Larsen
quelle
5

Erstellen Sie eine benutzerdefinierte TextWatcher-Unterklasse:

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

    }
}

Stellen Sie den Listener für Ihren EditText ein:

mTargetEditText.addTextChangedListener(new CustomWatcher());
Denis
quelle
Dies ist tatsächlich eine clevere und leichte Methode, um das Problem zu lösen! Vielen Dank!
FRR
2

Verwenden Sie für Kotlin die KTX-Erweiterungsfunktion : (Wird TextWatcherals vorherige Antwort verwendet)

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


Import core-KTX:

implementation "androidx.core:core-ktx:1.2.0"
Francis
quelle
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
quelle
1

wenn Sie mit dialog edittext implementieren. Verwenden Sie wie folgt:. das gleiche gilt für die Verwendung in anderen 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
quelle
-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()));
      }

         });

Für weitere Informationen klicken Sie hier http://androiddhina.blogspot.in/2015/05/android-textwatcher.html

Dhina k
quelle