爲了優化用戶體驗,咱們每每會在讓用戶輸入手機號碼時添加空格,好比:133 1234 5678
.那麼在Android中如何實現呢?java
Android中的輸入框EditText有個方法addTextChangedListener()
,該方法實現輸入框文字變更時的監聽.該方法須要傳入一個TextWatcher
接口的實現.git
TextWatcher
接口以下:github
public interface TextWatcher extends NoCopySpan {
public void beforeTextChanged(CharSequence s, int start, int count, int after);
public void onTextChanged(CharSequence s, int start, int before, int count);
public void afterTextChanged(Editable s);
}
複製代碼
該接口有三個回調函數,其含義以下:ide
public abstract void beforeTextChanged (CharSequence s, int start, int count, int after)
:函數
This method is called to notify you that, within s, the count characters beginning at start are about to be replaced by new text with length after. It is an error to attempt to make changes to s from this callback. 在字符串s內,從索引爲start(包含)的字符開始的count個字符將被長度爲after的新文本代替oop
public abstract void onTextChanged (CharSequence s, int start, int before, int count)
優化
This method is called to notify you that, within s, the count characters beginning at start have just replaced old text that had length before. It is an error to attempt to make changes to s from this callback. 在字符串s內,從索引爲start(包含)的字符開始count個字符剛剛替換了長度爲before的舊字符.;this
public abstract void afterTextChanged (Editable s)
spa
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. (You are not told where the change took place because other afterTextChanged() methods may already have made other changes and invalidated the offsets. But if you need to know here, you can use setSpan(Object, int, int, int) in onTextChanged(CharSequence, int, int, int) to mark your place and then look up from here where the span ended up. 字符串s內容已經發生了變化.能夠在這一步對s進行合理的變動,可是要注意不要進入無限循環,由於字符串的任何變化都會再次遞歸調用此回調方法.在這個方法中不會告訴你字符串哪些內容發生了變化,由於其餘針對字符串的改變已經調用了
afterTextChanged()
.若是你想知道哪些發生了變化,能夠在onTextChanged(CharSequence, int, int, int)
使用setSpan(Object, int, int, int)
作標記..net
看上面的解釋,是否是仍是有點糊塗呢?下面就用實例來解釋一下吧.
代碼很簡單,只有一個輸入框EditText
,而後添加一個TextWatcher
實現,將回調中的結果輸出.
public class MainActivity extends AppCompatActivity {
private EditText editText;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
editText = (EditText) findViewById(R.id.edit_text);
editText.addTextChangedListener(textWatcher);
}
private final TextWatcher textWatcher = new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
DLog.d("----------beforeTextChanged----------\n");
DLog.d("s:" + s + "\n");
DLog.d("start:" + start + "\n");
DLog.d("count:" + count + "\n");
DLog.d("after:" + after + "\n");
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
DLog.d("----------onTextChanged----------\n");
DLog.d("s:" + s + "\n");
DLog.d("start:" + start + "\n");
DLog.d("before:" + before + "\n");
DLog.d("count:" + count + "\n");
}
@Override
public void afterTextChanged(Editable s) {
DLog.d("----------afterTextChanged----------\n");
DLog.d("s:" + s + "\n");
}
};
}
複製代碼
其中Dlog
類參見此處:Android調試Log二次包裝
默認輸入框沒有任何內容,如下操做在上一步以後進行.
在輸入框輸入字符:1,各回調方法輸出的信息以下(註釋爲做者後來添加):
----------beforeTextChanged----------
s:
start:0
count:0
after:1
//註釋:在字符串""從索引0處開始的0個字符將被長度爲1的新字符串代替
//即""將被1代替
----------onTextChanged----------
s:1
start:0
before:0
count:1
//註釋:字符串"1"從索引0處開始的1個字符剛剛替換了長度爲0的舊字符串
//即1剛剛代替了""
----------afterTextChanged----------
s:1
//註釋:發生變化後的字符串爲:"1"
複製代碼
在輸入框一次性輸入字符(即粘貼):23,各回調方法輸出的信息以下(註釋爲做者後來添加):
----------beforeTextChanged----------
s:1
start:1
count:0
after:2
//註釋:在字符串"1"從索引1開始的0個字符將被長度爲2的新字符串代替
//即""將被23代替
----------onTextChanged----------
s:123
start:1
before:0
count:2
//註釋:字符串"123"從索引1開始的2個字符剛剛替換了長度爲0的舊字符串
//即23剛剛代替了""
----------afterTextChanged----------
s:123
//註釋:發生變化後的字符串爲:"123"
複製代碼
在輸入框一次性輸入字符(即粘貼):456,各回調方法輸出的信息以下(註釋爲做者後來添加):
----------beforeTextChanged----------
s:123
start:3
count:0
after:3
//註釋:在字符串"123"從索引3開始的0個字符將被長度爲3的新字符串代替
//即""將被456代替
----------onTextChanged----------
s:123456
start:3
before:0
count:3
//註釋:字符串"123456"從索引3開始的3個字符剛剛替換了長度爲0的舊字符串
//即456剛剛代替了""
----------afterTextChanged----------
s:123456
//註釋:發生變化後的字符串爲:"123456"
複製代碼
在輸入框刪除字符:6,各回調方法輸出的信息以下(註釋爲做者後來添加):
----------beforeTextChanged----------
s:123456
start:5
count:1
after:0
//註釋:在字符串"123456"從索引5開始的1個字符將被長度爲0的新字符串代替
//即6將被""代替
----------onTextChanged----------
s:12345
start:5
before:1
count:0
//註釋:字符串"12345"從索引5開始的0個字符剛剛替換了長度爲1的舊字符串
//即""剛剛代替了6
----------afterTextChanged----------
s:12345
//註釋:發生變化後的字符串爲:"12345"
複製代碼
在輸入框一次性刪除字符:45,各回調方法輸出的信息以下(註釋爲做者後來添加):
----------beforeTextChanged----------
s:12345
start:3
count:2
after:0
//註釋:在字符串"12345"從索引3開始的2個字符將被長度爲0的新字符串代替
//即45將被""代替
----------onTextChanged----------
s:123
start:3
before:2
count:0
//註釋:字符串"123"從索引3開始的0個字符剛剛替換了長度爲2的舊字符串
//即""剛剛代替了45
----------afterTextChanged----------
s:123
//註釋:發生變化後的字符串爲:"123"
複製代碼
在輸入框選中3粘貼爲ab,各回調方法輸出的信息以下(註釋爲做者後來添加):
----------beforeTextChanged----------
s:123
start:2
count:1
after:2
//註釋:在字符串"123"從索引2開始的1個字符將被長度爲2的新字符串代替
//即3將被ab代替
----------onTextChanged----------
s:12ab
start:2
before:1
count:2
//註釋:字符串"12ab"從索引2開始的2個字符剛剛替換了長度爲1的舊字符串
//即ab剛剛代替了3
----------afterTextChanged----------
s:12ab
//註釋:發生變化後的字符串爲:"12ab"
複製代碼
在輸入框選中ab粘貼爲3,各回調方法輸出的信息以下(註釋爲做者後來添加):
----------beforeTextChanged----------
s:12ab
start:2
count:2
after:1
//註釋:在字符串"12ab"從索引2開始的2個字符將被長度爲1的新字符串代替
//即ab將被3代替
----------onTextChanged----------
s:123
start:2
before:2
count:1
//註釋:字符串"123"從索引2開始的1個字符剛剛替換了長度爲2的舊字符串
//即3剛剛代替了ab
----------afterTextChanged----------
s:123
//註釋:發生變化後的字符串爲:"123"
複製代碼
在輸入框中2的後面輸入5,各回調方法輸出的信息以下(註釋爲做者後來添加):
----------beforeTextChanged----------
s:123
start:2
count:0
after:1
//註釋:在字符串"123"從索引2開始的0個字符將被長度爲1的新字符串代替
//即""將被5代替
----------onTextChanged----------
s:1253
start:2
before:0
count:1
//註釋:字符串"1253"從索引2開始的1個字符剛剛替換了長度爲0的舊字符串
//5剛剛代替了""
----------afterTextChanged----------
s:1253
//註釋:發生變化後的字符串爲:"1253"
複製代碼
從上面咱們能夠看出,在onTextChanged
方法中字符串已經發生變化,咱們能夠在此對用戶輸入的字符串追加空格. 用戶是一個數字一個數字的輸入到輸入框中,那麼條件爲:
字符串s從索引start開始的1個字符剛剛替換了""
public void onTextChanged(CharSequence s, int start, int before, int count) {
DLog.d("----------onTextChanged----------\n");
DLog.d("s:" + s + "\n");
DLog.d("start:" + start + "\n");
DLog.d("before:" + before + "\n");
DLog.d("count:" + count + "\n");
if (count == 1){
int length = s.toString().length();
if (length == 3 || length == 8){
editText.setText(s + " ");
editText.setSelection(editText.getText().toString().length());
}
}
}
複製代碼
當長度爲3和8時分別加上空格.
運行程序獲得結果以下:
更多文章請移步個人博客:DevWiki's Bolg