RecipientsEditor 新建短信時輸入收接者的editor,
public class RecipientsEditor extends MultiAutoCompleteTextView {
private int mLongPressedPosition = -1;
private final RecipientsEditorTokenizer mTokenizer;
private char mLastSeparator = ',';
public RecipientsEditor(Context context, AttributeSet attrs) {
super(context, attrs, android.R.attr.autoCompleteTextViewStyle);
mTokenizer = new RecipientsEditorTokenizer(context, this);
setTokenizer(mTokenizer);
// For the focus to move to the message body when soft Next is pressed
setImeOptions(EditorInfo.IME_ACTION_NEXT);
// Set threshold as 1 CharSequence.
setThreshold(1);
addTextChangedListener(new TextWatcher() {
private Annotation[] mAffected;
public void beforeTextChanged(CharSequence s, int start,
int count, int after) {
mAffected = ((Spanned) s).getSpans(start, start + count,
Annotation.class);
}
public void onTextChanged(CharSequence s, int start,
int before, int after) {
if (before == 0 && after == 1) { // inserting a character
char c = s.charAt(start);
if (c == ',' || c == ';') {
// Remember the delimiter the user typed to end this recipient. We'll
// need it shortly in terminateToken().
mLastSeparator = c;
}
}
}
public void afterTextChanged(Editable s) {
if (mAffected != null) {
for (Annotation a : mAffected) {
s.removeSpan(a);
}
}
mAffected = null;
}
});
}
RecipientsEditor 繼承於 MultiAutoCompleteTextView
可支持輸入多個手機號碼,每個手機號碼用用分隔符分開,有自動完成功能,預置匹配的數據爲聯繫人;
其中RecipientsEditorTokenizer爲了找出輸入字符串中的分隔符","和“,”
private class RecipientsEditorTokenizer
implements MultiAutoCompleteTextView.Tokenizer {
private final MultiAutoCompleteTextView mList;
private final Context mContext;
RecipientsEditorTokenizer(Context context, MultiAutoCompleteTextView list) {
mList = list;
mContext = context;
}
public int findTokenStart(CharSequence text, int cursor) {
int i = cursor;
char c;
while (i > 0 && (c = text.charAt(i - 1)) != ',' && c != ';') {
i--;
}
while (i < cursor && text.charAt(i) == ' ') {
i++;
}
return i;
}
public int findTokenEnd(CharSequence text, int cursor) {
int i = cursor;
int len = text.length();
char c;
while (i < len) {
if ((c = text.charAt(i)) == ',' || c == ';') {
return i;
} else {
i++;
}
}
return len;
}
public CharSequence terminateToken(CharSequence text) {
int i = text.length();
while (i > 0 && text.charAt(i - 1) == ' ') {
i--;
}
char c;
if (i > 0 && ((c = text.charAt(i - 1)) == ',' || c == ';')) {
return text;
} else {
// Use the same delimiter the user just typed.
// This lets them have a mixture of commas and semicolons in their list.
String separator = mLastSeparator + " ";
if (text instanceof Spanned) {
SpannableString sp = new SpannableString(text + separator);
TextUtils.copySpansFrom((Spanned) text, 0, text.length(),
Object.class, sp, 0);
return sp;
} else {
return text + separator;
}
}
}
setImeOptions(EditorInfo.IME_ACTION_NEXT);//設置軟鍵盤右下角的button的功能爲下一個,即切換到下一個輸入框,如果設置成EditorInfo.IME_ACTION_DONE,則表示輸入完成,關掉軟鍵盤,還有很多其他的選項可供設置的
setThreshold(1);// Threshold門檻的意思,此處設置只要輸入一個字符就開始匹配,若設置爲“2”則表示要輸入兩個字符纔是匹配。
addTextChangedListener(TextWatcher);//添加一個TextView監聽器
TextWatcher裏有三個回調方法,當有輸入框裏的字符有變化時會自動依次調用以下三個方法:
beforeTextChanged(CharSequence s, int start,int count, int after) ;
//此處已輸入爲例解釋上面各變量的意思,s 是輸入以前的字符串,start光標所在的位置, count爲要改變的字符個數,即選中的個數,after爲要插入的個數
onTextChanged(CharSequence s, int start, int before, int after)
//s爲改變後的字符串,start和上面的start一樣, before和上面的count一樣,after與上面的after一樣
afterTextChanged(Editable s)// s爲改變後的字符串
預製匹配數據爲聯繫人的方法是通過設置適配器:
mRecipientsEditor.setAdapter(new RecipientsAdapter(this));
RecipientsAdapter 是extends ResourceCursorAdapter的
在適配器裏面通過Phone.CONTENT_FILTER_URI,獲取電話本里的信息。