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,擷取電話本裡的資訊。