RecipientEditTextView在短信中的使用

来源:互联网 发布:redis与mysql结合 编辑:程序博客网 时间:2024/05/15 23:53

手头只有mtk的代码,短信代码位于在vendor/mediatek/proprietary/packages/apps/Mms,只能看MTKRecipientEditTextView的使用了。

ChipsRecipientAdapter

public class ChipsRecipientAdapter extends BaseRecipientAdapter
继承BaseRecipientAdapter,代码量很少。
    private static final int DEFAULT_PREFERRED_MAX_RESULT_COUNT = 10; //设置匹配列表项最大数量    public ChipsRecipientAdapter(Context context) {        super(context, DEFAULT_PREFERRED_MAX_RESULT_COUNT, QUERY_TYPE_PHONE); //设置uri是号码,因为默认是显示邮件地址        setShowDuplicateResults(false); //不显示重复的联系人    }    @Override    protected int getItemLayout() {        return R.layout.mms_chips_recipient_dropdown_item; //最主要的是替换了匹配列表项默认的布局显示    }

RecipientsEditor

public class RecipientsEditor extends MTKRecipientEditTextView
继承了MTKRecipientEditTextView

验证器

控件用到的字符串验证器,不做任何处理。
    private class AddressValidator implements Validator {        public CharSequence fixText(CharSequence invalidText) {            return invalidText; //直接返回源字符,不做处理        }        public boolean isValid(CharSequence text) {            return true; //所有字符都是合法的,不做判断        }    }

搜索延时

设置搜索延时,不会输入字符就马上搜索,处理连续输入字符的情况,减少代码处理量
    public void setGalSearchDelayer() {        Filter filter = getFilter();        if (filter != null) {            filter.setDelayer(new Filter.Delayer() {                private int mPreviousLength = 0;                public long getPostingDelay(CharSequence constraint) {                    if (constraint == null) {                        return 0;                    }                    long delay = constraint.length() < mPreviousLength                            ? DELETE_KEY_POST_DELAY : ADD_POST_DELAY;                    mPreviousLength = constraint.length();                    return delay;                }            });        }    }


标记器

    private class RecipientsEditorTokenizer            implements MultiAutoCompleteTextView.Tokenizer 
其中的findTokenStart和findTokenEnd用于确认一个token的开始和结束,使用它才能拆分出字符串中的一个个号码。


构造方法

除了上述的几个重要对象外,其它的重要代码如下:
    public RecipientsEditor(Context context, AttributeSet attrs) {        ...        setThreshold(1);    // 设置1个字符起就要显示匹配列表        /// M:        setInputType(getInputType() | InputType.TYPE_TEXT_FLAG_MULTI_LINE); //设置可以输入多行字符        ...        if (!getResources().getBoolean(R.bool.isWVGAScreen)) {            setMaxLines(3); //可以配置控件行数最多为3行        } else {            setMaxLines(1);        }               addTextChangedListener(new TextWatcher() {...}); 从匹配列表选择的号码会有Annotation类型的Span,如果修改号码就要去除该Span    }

生成数据

从会话列表进入某个会话,当然要填充联系人数据,这个方法就是populate
    public void populate(ContactList list) {   // ContactList是短信应用中的类             if (list.size() == 0) {            setText(null);        } else {                  MTKRecipientList recipientList = new MTKRecipientList(); //MTKRecipientList是控件库中的类            for (Contact c : list) {                String displayName = c.getName();                if (!TextUtils.isEmpty(displayName) && displayName.equals(c.getNumber())) {                    displayName = "";                }                MTKRecipient recipient = new MTKRecipient(displayName, c.getNumberProtosomatic()); //MTKRecipient也是是控件库中的类                recipientList.addRecipient(recipient);            }            appendList(recipientList); //使用控件中的方法        }    }

从ChipWatcher中解析数据


 public void parseRecipientsFromChipWatcher(ArrayList<RecipientEntry> recipientList, ArrayList<String> changedNumbers, String lastRecipient, int limit)
这个方法其实就是对应MTKRecipientEditTextView控件中的
    public interface ChipWatcher {        public void onChipChanged(ArrayList<RecipientEntry> allChips, ArrayList<String> changedChipAddresses, String lastString);    }
chip数据有变化的时候通知应用。


ComposeMessageActivity中的使用

短信主要的只有两个界面,一个是会话列表,另外一个就是会话。该类就是会话界面
    private RecipientsEditor mRecipientsEditor;  // UI control for editing recipients     控件实例    private ImageButton mRecipientsPicker;       // UI control for recipients picker     mRecipientsEditor右面选取联系人的按键


ChipWatcher

实现了ChipWatcher接口,代替了TextWatcher。功能有二:一是减少了调用次数,例如删除个空格键是不会引起ChipWatcher的调用的,而TextWatcher只要有变化就会引起回调;二是实现了联系人信息的更新,因为text内容不变但是联系人数据库可以变,例如一个无主号码因为联系人的添加而要显示成为一个联系人chip。
private final MTKRecipientEditTextView.ChipWatcher mChipWatcher = new MTKRecipientEditTextView.ChipWatcher() {...}

该实现中主要是使用之前提及的parseRecipientsFromChipWatcher方法解析数据,然后更新其它相关数据结构。


ContextMenu

    private final OnCreateContextMenuListener mRecipientsMenuCreateListener =        new OnCreateContextMenuListener() {        @Override        public void onCreateContextMenu(ContextMenu menu, View v,                ContextMenuInfo menuInfo) {            mChipViewMenu = menu;            if (menuInfo != null) {                Contact c = ((RecipientContextMenuInfo) menuInfo).recipient;                RecipientsMenuClickListener l = new RecipientsMenuClickListener(c); //菜单点击处理                menu.setHeaderTitle(c.getName());                if (c.existsInDatabase()) {                    menu.add(0, MENU_VIEW_CONTACT, 0, R.string.menu_view_contact)                            .setOnMenuItemClickListener(l); //查看联系人详情                } else if (MessageUtils.canAddToContacts(c)) {                    menu.add(0, MENU_ADD_TO_CONTACTS, 0, R.string.menu_add_to_contacts)                            .setOnMenuItemClickListener(l); //添加联系人                }            }        }    };
RecipientsMenuClickListener处理代码就是发送intent,很简单

控件初始化

初始化都在initRecipientsEditor方法中

    private void initRecipientsEditor(Bundle bundle) {              ContactList recipients = getRecipients(); //获取会话联系人数据        while (!recipients.isEmpty() && recipients.size() > RECIPIENTS_LIMIT_FOR_SMS) {             recipients.remove(RECIPIENTS_LIMIT_FOR_SMS);//这里限制了短信发送人数上限是100,多于100后面的删掉        }        ...        mRecipientsEditor = (RecipientsEditor) stubView.findViewById(R.id.recipients_editor);        ...             mRecipientsEditor.addChipChangedListener(mChipWatcher); //设置ChipWatcher            ...        if (mRecipientsEditor.getAdapter() == null) { //设置匹配列表adapter,搜索uri和延时            ChipsRecipientAdapter chipsAdapter = new ChipsRecipientAdapter(this);            chipsAdapter.setShowEmailAddress(showEmailAddress);            mRecipientsEditor.setAdapter(chipsAdapter);            mRecipientsEditor.setGalSearchDelayer();        }         ...        mRecipientsEditor.populate(recipients); //初始化数据                mRecipientsEditor.setOnCreateContextMenuListener(mRecipientsMenuCreateListener); //ConextMenu初始化        mRecipientsEditor.setOnSelectChipRunnable(...); //号码为一个的时候,点击弹出输入法        mRecipientsEditor.setOnFocusChangeListener(...); //获取焦点的时候调整短信内容空间的高度        ...    }

0 0
原创粉丝点击