Làm thế nào để sử dụng lớp TextWatcher trong Android?


103

Bất cứ ai có thể cho tôi biết cách che chuỗi con trong EditTexthoặc cách thay đổi EditText đầu vào chuỗi con thành loại mật khẩu hoặc thay thế bằng một ký tự khác như thế này 123xxxxxxxxx3455

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

Vui lòng cho tôi biết cách tôi có thể sử dụng TextWatcherphương pháp này trong Android.

Câu trả lời:


174

Để sử dụng 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
phải làm gì với TextWatcher này? Cung cấp thêm chi tiết để hiểu rõ hơn.
Paresh Mayani

Trong phương thức được ghi đè cho trình xem văn bản. bạn có thể che văn bản mà bạn thực sự muốn.
Dinesh Prajapati

2
nhưng tôi không biết làm thế nào để sử dụng TextWatcher u có thể giải thích với rất ít ví dụ nhờ để được hướng dẫn ur
nhà phát triển Android

đặt mã này trong java..và ngay sau khi người dùng nhập văn bản, một trong các phương thức sẽ được gọi ... theo tên của hàm.
Dinesh Prajapati

1
Trên thực tế nếu điều này là yêu cầu thì tốt hơn không sử dụng văn bản watcher.it đang xảy ra để lặp vô hạn
Dinesh Prajapati

119

Các TextWatchergiao diện có 3 phương pháp callbacks được tất cả gọi theo thứ tự sau khi một sự thay đổi xảy ra với nội dung:

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

Được gọi trước khi các thay đổi được áp dụng cho văn bản.
Các stham số là các văn bản trước khi bất kỳ thay đổi được áp dụng.
Các starttham số là vị trí của đầu phần thay đổi trong văn bản.
Các counttham số là chiều dài của phần thay đổi trong schuỗi từ startvị trí.
aftertham số là độ dài của chuỗi mới sẽ thay thế một phần của schuỗi từ startđến start+count.
Bạn không được thay đổi văn bản trong TextViewtừ phương pháp này (bằng cách sử dụng myTextView.setText(String newText)).

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

Tương tự như beforeTextChangedphương thức nhưng được gọi sau khi văn bản thay đổi.
Các stham số là các văn bản sau khi thay đổi đã được áp dụng.
Các starttham số là giống như trong các beforeTextChangedphương pháp.
Các counttham số là aftertham số trong phương pháp beforeTextChanged.
beforetham số là counttham số trong phương thức beforeTextChanged.
Bạn không được thay đổi văn bản trong TextViewtừ phương pháp này (bằng cách sử dụng myTextView.setText(String newText)).

afterTextChanged(Editable s)

Bạn có thể thay đổi văn bản trong TextViewtừ phương pháp này.
/! \ Cảnh báo: Khi bạn thay đổi văn bản trong TextView, TextWatchersẽ được kích hoạt lại, bắt đầu một vòng lặp vô hạn. Sau đó, bạn nên thêm giống như một thuộc boolean _ignoretính ngăn vòng lặp vô hạn.
Thực hiện:

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

Tóm lược:

nhập mô tả hình ảnh ở đây


Một lớp sẵn sàng để sử dụng: TextViewListener

Cá nhân tôi đã tạo trình nghe văn bản tùy chỉnh của mình, cung cấp cho tôi 4 phần trong các chuỗi riêng biệt, đối với tôi, sử dụng trực quan hơn nhiều.

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

Thí dụ:

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

Vấn đề với mã này là con trỏ không ở lại như nó được cho là hoặc ít nhất đó là kinh nghiệm của tôi.
jonasxd360

Là nó TextView mà các cuộc gọi các phương pháp này

Tôi cũng nghĩ vậy
Yairopro

vấn đề cố định với con trỏ như sau: protected void OnTextChanged (String trước, String cũ, String Anew, String sau, Editable chuỗi)
Eugene Strelnikov

49

Câu trả lời bổ sung

Đây là phần bổ sung trực quan cho các câu trả lời khác. Câu trả lời đầy đủ hơn của tôi với mã và giải thích ở đây .

  • Màu đỏ: văn bản sắp bị xóa (thay thế)
  • Màu xanh lá cây: văn bản vừa được thêm vào (thay thế văn bản màu đỏ cũ)

nhập mô tả hình ảnh ở đây


6

Sử dụng TextWatcher trong Android

Đây là một mã mẫu. Thử sử dụng addTextChangedListenerphương pháp 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);
            }
        }
    });

5

Một góc nhìn lớn hơn một chút về giải pháp:

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

Điều này làm việc cho tôi, làm nó lần đầu tiên của tôi.


5

Tạo lớp con TextWatcher tùy chỉnh:

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

    }
}

Đặt trình nghe cho EditText của bạn:

mTargetEditText.addTextChangedListener(new CustomWatcher());

Đây thực sự là một cách giải quyết vấn đề thông minh, gọn nhẹ! cảm ơn!
FRR

2

Đối với Kotlin, sử dụng hàm mở rộng KTX : (Nó sử dụng TextWatchernhư các câu trả lời trước)

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


nhập khẩu core-KTX:

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

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

1

nếu bạn triển khai bằng văn bản chỉnh sửa hộp thoại. sử dụng như thế này:. nó tương tự với việc sử dụng các văn bản chỉnh sửa khác.

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

         });

Để tham khảo thêm, hãy nhấp vào đây http://androiddhina.blogspot.in/2015/05/android-textwatcher.html

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.