Android에서 TextWatcher 클래스를 사용하는 방법은 무엇입니까?


103

사람이 마스크하는 방법을 말해 줄 수 문자열을EditText또는 변경하는 방법 EditText 암호 유형에 하위 문자열 입력을 하거나 대체 할 다른 의해 성격 이 123xxxxxxxxx3455 같은

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

TextWatcherAndroid 에서 방법을 사용하는 방법을 알려주십시오 .

답변:


174

의 사용을 위해 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
이 TextWatcher로 무엇을 할 수 있습니까? 더 나은 이해를 위해 더 자세한 정보를 제공하십시오.
Paresh Mayani 2011

텍스트 감시자에 대해 재정의 된 메서드에서. 정말로 원하는 텍스트를 가릴 수 있습니다.
Dinesh Prajapati

2
하지만 TextWatcher를 사용하는 방법을 모르겠습니다. 지침에 대한 작은 예 감사로 설명 할 수 있습니다.
Android 개발자

사용자가 입력하자마자이 코드를 java ..에 넣으십시오. 함수의 이름에 따라 메소드 중 하나가 호출됩니다.
Dinesh Prajapati 2011

1
이 요구 사항이 사실이라면 더 나은 텍스트 watcher.it의 무한 루프에 갈 사용하지
네쉬 Prajapati

119

TextWatcher인터페이스는 변화가 발생한 경우 텍스트 모두 다음과 같은 순서로 불리는 3 콜백 방법이있다 :

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

변경 사항이 텍스트에 적용 되기 전에 호출 됩니다. 매개 변수입니다 전에 텍스트 변경이 적용됩니다. 매개 변수는입니다 위치 텍스트의 변경된 부분의 시작. 매개 변수 인 길이 의 변경된 부분 사람 서열 의 총수. 그리고 매개 변수는 인 새로운 시퀀스의 길이 의 부분 대체 할 에서 순서 에 . 당신은 변경하지 않아야합니다 의 텍스트를 이 방법에서 (사용 ).
s
start
countsstart
aftersstartstart+count
TextViewmyTextView.setText(String newText)

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

받는 비슷한 beforeTextChanged방법이지만라는 한 후 텍스트가 변경됩니다. 매개 변수입니다 후 텍스트 변경 사항이 적용되고있다. 파라미터는 동일하다 방법. 매개 변수이다 beforeTextChanged 방법에서 파라미터. 그리고 매개 변수는 beforeTextChanged 메소드 의 매개 변수입니다. 당신은 변경하지 않아야합니다 의 텍스트를 이 방법에서 (사용 ).
s
startbeforeTextChanged
countafter
beforecount
TextViewmyTextView.setText(String newText)

afterTextChanged(Editable s)

이 방법에서 의 텍스트를 변경할있습니다TextView .
/ \ 경고 :! 당신의 텍스트를 변경하는 경우 TextView는이 TextWatcher무한 루프를 시작, 다시 트리거됩니다. 그런 다음 boolean _ignore무한 루프를 방지 하는 속성 을 추가해야 합니다.
예 :

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

요약:

여기에 이미지 설명 입력


즉시 사용할 수있는 클래스 : TextViewListener

개인적으로 사용자 지정 텍스트 리스너를 만들어 별도의 문자열로 4 개 부분을 제공하여 사용하기 훨씬 더 직관적입니다.

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

예:

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

이 코드의 문제는 커서가 있어야하거나 적어도 내 경험이었던 경우 커서가 유지되지 않는다는 것입니다.
jonasxd360

이 메서드를 호출하는

나는 그렇게 생각한다
Yairopro

이 방법으로 커서를 고정 문제 : 무효 onTextChanged 보호 (문자열 전에, 문자열 이전, 문자열 새롭게, 문자열 후, 편집 순서)
유진 Strelnikov

49

추가 답변

다음은 다른 답변에 대한 시각적 보충 자료입니다. 코드와 설명에 대한 자세한 답변은 여기에 있습니다 .

  • 빨간색 : 삭제 될 텍스트 (바꾸기)
  • 녹색 : 방금 추가 된 텍스트 (이전 빨간색 텍스트 대체)

여기에 이미지 설명 입력


6

Android에서 TextWatcher 사용

다음은 샘플 코드입니다. addTextChangedListenerTextView의 방법을 사용해보십시오

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

솔루션에 대한 좀 더 큰 관점 :

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

이것은 나를 위해 작동하며 처음으로 수행합니다.


5

사용자 지정 TextWatcher 하위 클래스를 만듭니다.

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에 대한 리스너를 설정하십시오.

mTargetEditText.addTextChangedListener(new CustomWatcher());

이것은 실제로 문제를 해결하는 영리하고 가벼운 방법입니다! 감사!
FRR

2

들어 코 틀린의 사용 KTX 확장 기능 : (그것은 사용 TextWatcher이전의 답변으로)

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


수입 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

대화 편집 텍스트로 구현하는 경우. 다음과 같이 사용하십시오. 다른 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) {

    }
});

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

         });

더 많은 참조를 원하시면 여기를 클릭하십시오 http://androiddhina.blogspot.in/2015/05/android-textwatcher.html

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.