android源碼追蹤學習 RecipientsEditor

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,獲取電話本里的信息。



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章