TextWatcher sınıfı Android'de nasıl kullanılır?


104

Herkes maske nasıl söyleyebilir alt dizeyi içinde EditTextveya nasıl değiştirileceği EditText şifre tipine alt dize girişi veya değiştirme başkası tarafından karakteri bu 123xxxxxxxxx3455 gibi

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

Lütfen, TextWatcheryöntemi Android'de nasıl kullanabileceğimi söyleyin .

Yanıtlar:


174

Kullanım için 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
    }
});

59
bu TextWatcher ile ne yapmalı? Daha iyi anlamak için daha fazla ayrıntı sağlayın.
Paresh Mayani

Metin izleyici için geçersiz kılınan yöntemde. gerçekten istediğiniz metni maskeleyebilirsiniz.
Dinesh Prajapati

2
ancak TextWatcher'ı nasıl kullanacağımı bilmiyorum, biraz örnekle açıklayabilirsin, yönergeler için teşekkürler
Android geliştiricisi

bu kodu java'ya koyun .. kullanıcı metni yazdığı anda yöntemlerden biri fonksiyonun adına göre ... çağrılacaktır.
Dinesh Prajapati

1
Aslında bu şartsa, metin izleyiciyi kullanmamak daha iyi. Sonsuz döngüye girecek
Dinesh Prajapati

120

TextWatcherArayüzü bir değişiklik metne meydana geldiği aşağıdaki sırada çağrılan 3 geri çağrıları yöntem vardır:

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

Değişiklikler metne uygulanmadan önce çağrılır . Parametredir önce metni herhangi bir değişiklik uygulanmaz. Parametredir pozisyon metninde değiştirilen parçanın başından. Parametredir uzunluğu değiştirilen parçasının yana sekansı pozisyon. Ve parametredir yeni dizi uzunluğu parçası yerini alacak sekans için . Sen değiştirmemelidir metni bu yöntemi kullanarak ( ).
s
start
countsstart
aftersstartstart+count
TextViewmyTextView.setText(String newText)

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

beforeTextChangedYönteme benzer ancak metin değiştikten sonra çağrılır . Parametredir sonra metin değişiklikler uygulandı. Parametre aynıdır yöntem. Parametredir beforeTextChanged yönteminde parametresi. Ve parametre, beforeTextChanged yöntemindeki parametredir. Sen değiştirmemelidir metni bu yöntemi kullanarak ( ).
s
startbeforeTextChanged
countafter
beforecount
TextViewmyTextView.setText(String newText)

afterTextChanged(Editable s)

Sen değiştirebilir metni TextViewbu yöntemden.
/ \ Uyarı:! Eğer metin değiştirdiğinizde TextView, TextWatchersonsuz döngü başlayarak tekrar tetiklenir. Sonra boolean _ignoresonsuz döngüyü engelleyen bir özellik gibi eklemelisiniz .
Örnek:

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

Özet:

görüntü açıklamasını buraya girin


Kullanıma hazır bir sınıf: TextViewListener

Şahsen, özel metin dinleyicimi yaptım, bu bana 4 parçayı ayrı dizelerde veriyor, bu benim için kullanımı çok daha sezgisel.

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

Misal:

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

Bu kodla ilgili sorun, imlecin olması gerektiği gibi kalmaması veya en azından benim deneyimim buydu.
jonasxd360

Bu yöntemleri çağıran

Sanırım öyle
Yairopro

imleç ile ilgili bu şekilde sorun çözüldü: korumalı void onTextChanged (Önceki dize, Eski dize, Dize aYeni, Sonra dize, Düzenlenebilir sıra)
Eugene Strelnikov

50

Tamamlayıcı cevap

İşte diğer cevapların görsel bir tamamlayıcısı. Kod ve açıklamalarla daha kapsamlı cevabım burada .

  • Kırmızı: silinmek üzere olan metin (değiştirilecek)
  • Yeşil: yeni eklenen metin (eski kırmızı metnin yerini alıyor)

görüntü açıklamasını buraya girin


6

TextWatcher'ı Android'de Kullanma

İşte örnek bir kod. addTextChangedListenerTextView yöntemini kullanmayı deneyin

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

5

Çözümün biraz daha büyük bir perspektifi:

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

Bu benim için çalışıyor, ilk seferimde yapıyor.


5

Özel TextWatcher alt sınıfı oluşturun:

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

    }
}

EditText'iniz için dinleyici ayarlayın:

mTargetEditText.addTextChangedListener(new CustomWatcher());

Bu aslında sorunu çözmenin akıllıca ve hafif bir yoludur! Teşekkürler!
FRR

3

İçin Kotlin Kullanım ktx uzatma fonksiyonu: (O kullanır TextWatcherönceki cevapları gibi)

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


içe aktar core-KTX:

implementation "androidx.core:core-ktx:1.2.0"

bu benim için çalışıyor
adrian4aes

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

2

dialog edittext ile uygularsanız. bunun gibi kullanın :. diğer edittext kullanımıyla aynı.

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

    }
});

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

         });

Daha fazla referans için buraya tıklayın http://androiddhina.blogspot.in/2015/05/android-textwatcher.html

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.