Bagaimana cara menggunakan kelas TextWatcher di Android?

103

Bisa ada yang bilang saya bagaimana untuk menutupi substring di EditTextatau bagaimana mengubah EditText substring masukan untuk jenis sandi atau mengganti dengan yang lain karakter seperti 123xxxxxxxxx3455 ini

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

Tolong, beri tahu saya bagaimana saya bisa menggunakan TextWatchermetode ini di Android.

Pengembang Android
sumber

Jawaban:

174

Untuk penggunaan 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
sumber
59
apa yang harus dilakukan dengan TextWatcher ini? Berikan lebih banyak detail untuk pemahaman yang lebih baik.
Paresh Mayani
Dalam metode yang diganti untuk pengamat teks. Anda dapat menutupi teks yang benar-benar Anda inginkan.
Dinesh Prajapati
2
tetapi saya tidak tahu cara menggunakan TextWatcher, bisakah Anda menjelaskan dengan sedikit contoh terima kasih untuk pedoman Anda
Pengembang Android
letakkan kode ini di java .. segera setelah pengguna mengetik teks, salah satu metode akan dipanggil ... sesuai dengan nama fungsinya.
Dinesh Prajapati
1
Sebenarnya jika ini adalah persyaratannya maka lebih baik tidak menggunakan pengamat teks. Ini akan menjadi loop tak terbatas
Dinesh Prajapati
119

The TextWatcherantarmuka memiliki 3 callback metode yang semuanya disebut dalam urutan berikut ketika perubahan terjadi pada teks:

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

Dipanggil sebelum perubahan diterapkan ke teks.
The sparameter teks sebelum perubahan diterapkan.
The startparameter adalah posisi dari awal bagian berubah dalam teks.
The countparameter adalah panjang dari bagian berubah dalam surutan sejak startposisi.
Dan afterparameternya adalah panjang urutan baru yang akan menggantikan bagian surutan dari startmenjadi start+count.
Anda tidak boleh mengubah teks diTextView from metode ini (dengan menggunakan myTextView.setText(String newText)).

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

Mirip dengan beforeTextChangedmetode tetapi dipanggil setelah teks berubah.
The sparameter teks setelah perubahan telah diterapkan.
The startparameter adalah sama seperti dalam beforeTextChangedmetode.
The countparameter adalah afterparameter dalam metode beforeTextChanged.
Dan beforeparameternya adalah countparameter dalam metode beforeTextChanged.
Anda tidak boleh mengubah teks di TextViewfrom metode ini (dengan menggunakan myTextView.setText(String newText)).

afterTextChanged(Editable s)

Anda dapat mengubah teks di TextViewfrom metode ini.
/! \ Peringatan: Ketika Anda mengubah teks di TextView, itu TextWatcherakan dipicu lagi, memulai loop tak terbatas. Anda kemudian harus menambahkan seperti boolean _ignoreproperti yang mencegah pengulangan tak terbatas.
Contoh:

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

Ringkasan:

masukkan deskripsi gambar di sini


Kelas siap pakai: TextViewListener

Secara pribadi, saya membuat pendengar teks khusus saya, yang memberi saya 4 bagian dalam string terpisah, yang, bagi saya, jauh lebih intuitif untuk digunakan.

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

Contoh:

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
sumber
Masalah dengan kode ini adalah bahwa kursor tidak tetap semestinya atau setidaknya itulah pengalaman saya.
jonasxd360
Apakah textview yang memanggil metode ini
Saya rasa begitu
Yairopro
memperbaiki masalah dengan kursor dengan cara ini: protected void onTextChanged (String before, String old, String aNew, String after, Editable sequence)
Eugene Strelnikov
49

Jawaban tambahan

Berikut adalah tambahan visual untuk jawaban lainnya. Jawaban lengkap saya dengan kode dan penjelasannya ada di sini .

  • Merah: teks akan dihapus (diganti)
  • Hijau: teks yang baru saja ditambahkan (menggantikan teks merah lama)

masukkan deskripsi gambar di sini

Suragch
sumber
6

Menggunakan TextWatcher di Android

Berikut ini contoh kode. Coba gunakan addTextChangedListenermetode 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
sumber
5

Perspektif solusi yang sedikit lebih besar:

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

Ini berhasil untuk saya, melakukannya untuk pertama kalinya.

Berit Larsen
sumber
5

Buat subkelas TextWatcher khusus:

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

    }
}

Setel pendengar untuk EditText Anda:

mTargetEditText.addTextChangedListener(new CustomWatcher());
Denis
sumber
Ini sebenarnya adalah cara yang cerdas dan ringan untuk memecahkan masalah! Terima kasih!
FRR
2

Untuk Kotlin gunakan fungsi ekstensi KTX : ( Digunakan sebagai jawaban sebelumnya)TextWatcher

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


impor core-KTX:

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

jika Anda menerapkan dengan dialog edittext. gunakan seperti ini: Ini sama dengan penggunaan untuk teks editan lainnya.

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

         });

Untuk referensi lebih lanjut klik di sini http://androiddhina.blogspot.in/2015/05/android-textwatcher.html

Dhina k
sumber