0. TextWatcher
User input을 처리할 때 phone number를 어떻게 처리하면 좋을까?
예를 들어 01112345678을 입력으로 받았을 때 011-1234-5678 이렇게 보여주고 싶다면? 안드로이드에서 기본적으로
PhoneNumberFormattingTextWatcher class를 제공해 주고 있다.
아래 코드 처럼 간단하다
etPhone.addTextChangedListener(new PhoneNumberFormattingTextWatcher());
1. Customize TextWatcher
price를 입력한다고 했을 때 쉼표를 넣어 주는 것을 고려해 보자. 이것은 android에서 제공하지 않기 때문에 아래와 같이 만들어 보았다.
public class PriceFormattingTextWatcher implements TextWatcher{
/**
* Indicates the change was caused by ourselves.
*/
private boolean mSelfChange = false;
@Override
public void beforeTextChanged(CharSequence s, int start, int count,
int after) {
if (mSelfChange)
return;
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
if (mSelfChange)
return;
}
@Override
public synchronized void afterTextChanged(Editable s) {
if (mSelfChange) {
// Ignore the change caused by s.replace().
return;
}
String formatted = null;
if(s.length() > 0){
NumberFormat nf = NumberFormat.getInstance();
String userInput= ""+s.toString().replaceAll("[^\\d]", "");
formatted = String.valueOf(nf.format(Float.parseFloat(userInput)));
}
if (formatted != null) {
mSelfChange = true;
s.setFilters(new InputFilter[]{});
s.replace(0, s.length(), formatted, 0, formatted.length());
mSelfChange = false;
}
}
}
1,234 에서 2를 삭제했을 때 제일 먼저 beforeTextChanged()가 호출 되고 이때 값은 1,234이다. 이후 onTextChanged() 가 호출되고 이때 값은 1,34이다.
2. 주의사항
public abstract void afterTextChanged (Editable s)
This method is called to notify you that, somewhere within s, the text has been changed. It is legitimate to make further changes to s from this callback, but be careful not to get yourself into an infinite loop, because any changes you make will cause this method to be called again recursively.
사용자가 변경한 내용이 다시 callback 함수를 호출하여 무한 루프에 빠질 수 있으니 코드 작성에 주의해야 한다. 위 예제에서 mSelfChange 변수를 주목하자.