短信ui-会话编辑界面(二)接收者UI

1、前沿

通过前面http://blog.csdn.net/ceko_wu/article/details/8201193 基础知识的学习,接收者UI 比较简单,下面就来看看它的功能是怎么实现的。

2、功能分析


这个UI 是很简单的,上篇文章有简单介绍,只有当新建会话的时候才会显示该UI,打开已存在的会话不会显示该UI。
LinearLayout            android:layout_width="match_parent"            android:layout_height="wrap_content"            android:orientation="horizontal">            <ViewStub android:id="@+id/recipients_editor_stub"                android:layout="@layout/recipients_editor"                android:layout_width="0dip"                android:layout_height="wrap_content"                android:layout_weight="1.0"            />            <ViewStub android:id="@+id/add_recipients_bt_stub"                android:layout="@layout/add_recipients_bt"                android:layout_width="wrap_content"                android:layout_height="wrap_content"                android:layout_marginLeft="5dip"            />        </LinearLayout>        <EditText android:id="@+id/subject"            android:layout_width="match_parent"            android:layout_height="wrap_content"            android:capitalize="sentences"            android:autoText="true"            android:singleLine="true"            android:maxLength="40"            android:hint="@string/subject_hint"            android:visibility="gone"/>
从上面布局文件来看也就三个,其中主题UI很简单所以不做具体分析:

2.1 是接收者编辑框简介

该编辑框不是一个简单的EditTextview,通过看 layout/recipients_editor你可以发现
<com.android.mms.ui.RecipientsEditor    xmlns:android="http://schemas.android.com/apk/res/android"    android:id="@+id/recipients_editor"    android:hint="@string/to_hint"    android:layout_width="match_parent"    android:layout_height="wrap_content"    android:inputType="textFilter"    />
查看RecipientsEditor类
public class RecipientsEditor extends MultiAutoCompleteTextView {

这里大家可能比较疑惑,为什么不使用一般的EditTextView,而使用自定义的MultiAutoCompleteTextView ,它与一般的EditTextView的差异:
首先 它可以处理接收者的内容,对于其内容的编辑处理,添加联系人有两种方式:一是手动编写,二是从通讯录中添加联系人。其次是该类有一个自动提供建议的功能,例如用户输入100,程序会去检索100相关的联系人并显示,用户根据自己的要求选择,类似于自动补全功能。

2.2 编辑框 对联系人的处理

首先来看看该UI初始化的时候做了哪些操作,设置了哪些监听。
   private void initRecipientsEditor() {        ContactList recipients = getRecipients();        ViewStub stub = (ViewStub)findViewById(R.id.recipients_editor_stub);        if (stub != null) {            mRecipientsEditor = (RecipientsEditor) stub.inflate();        } else {            mRecipientsEditor = (RecipientsEditor)findViewById(R.id.recipients_editor);初始化编辑框            mRecipientsEditor.setVisibility(View.VISIBLE);        }        stub = (ViewStub)findViewById(R.id.add_recipients_bt_stub);初始化添加按钮        mAddRecipientButton.setOnClickListener(this);添加按钮设置监听器        mRecipientsEditor.setAdapter(new RecipientsAdapter(this));设置自动补全的adapter        mRecipientsEditor.populate(recipients);同步联系人        mRecipientsEditor.setOnCreateContextMenuListener(mRecipientsMenuCreateListener);设置长按menu        mRecipientsEditor.addTextChangedListener(mRecipientsWatcher);设置文件watcher        mRecipientsEditor.setOnItemClickListener(new AdapterView.OnItemClickListener() {用户点击联系人子项时的点击事件处理            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {                if (mRecipientsEditor.getRecipientCount() == 1) {                    final InputMethodManager inputManager = (InputMethodManager)                        getSystemService(Context.INPUT_METHOD_SERVICE);                    if (inputManager == null || !inputManager.isFullscreenMode()) {                        mTextEditor.requestFocus();                    } }}});        mRecipientsEditor.setOnFocusChangeListener(new View.OnFocusChangeListener() {当foucus状态发生变化时更新activity的title            public void onFocusChange(View v, boolean hasFocus) {                if (!hasFocus) {                    RecipientsEditor editor = (RecipientsEditor) v;                    ContactList contacts = editor.constructContactsFromInput();                    updateTitle(contacts); } } });
上面做了两个重要的操作,一个是设置自动补全的adapter,另一个是设置文本的watcher。

2.2.1 文本watcher

首先来看看设置的文本watcher有什么作用,实现了哪些功能.
    private final TextWatcher mRecipientsWatcher = new TextWatcher() {        public void beforeTextChanged(CharSequence s, int start, int count, int after) {        }        public void onTextChanged(CharSequence s, int start, int before, int count) {            onUserInteraction();        }        public void afterTextChanged(Editable s) {            if (!isRecipientsEditorVisible()) {                IllegalStateException e = new IllegalStateException(                        "afterTextChanged called with invisible mRecipientsEditor");                return;            }            mWorkingMessage.setWorkingRecipients(mRecipientsEditor.getNumbers());            mWorkingMessage.setHasEmail(mRecipientsEditor.containsEmail(), true);            checkForTooManyRecipients();            updateTitle(mRecipientsEditor.constructContactsFromInput());            for (int pos = s.length() - 1; pos >= 0; pos--) {                char c = s.charAt(pos);                if (c == ' ')                    continue;                if (c == ',') {                    updateTitle(mConversation.getRecipients());                }                break;            }            updateSendButtonState();        }    };
该watcher做的工作很简单,就是讲添加的联系人同步,检查联系人是否查出限制,更新title,更新发送按钮的状态。

2.2.2 自动补全功能

自动补全是怎么实现的,来看看设置的adapter,之所以没有讲这个adapter是怎么和控件来实现的,其内部原理没有讲解,是因为这里的控件是MultiAutoCompleteTextView ,该控件就是自带这个功能,在sdk中有相关说明,所以这里就不做进一步分析。那该adpater就是用于将查询出的相关的联系人绑定到view上显示。
    @Override    public Cursor runQueryOnBackgroundThread(CharSequence constraint) {        String phone = "";        String cons = null;        if (constraint != null) {            cons = constraint.toString();            if (usefulAsDigits(cons)) {                phone = PhoneNumberUtils.convertKeypadLettersToDigits(cons);                if (phone.equals(cons)) {                    phone = "";                } else {                    phone = phone.trim();}} }        Cursor phoneCursor =            mContentResolver.query(uri,                    PROJECTION_PHONE,                    null, //selection,                    null,                    SORT_ORDER);        if (phone.length() > 0) {            ArrayList result = new ArrayList();            result.add(Integer.valueOf(-1));                    // ID            result.add(Long.valueOf(-1));                       // CONTACT_ID            result.add(Integer.valueOf(Phone.TYPE_CUSTOM));     // TYPE            result.add(phone);                                  // NUMBER            result.add("\u00A0");                               // LABEL            result.add(cons);                                   // NAME            ArrayList<ArrayList> wrap = new ArrayList<ArrayList>();            wrap.add(result);            ArrayListCursor translated = new ArrayListCursor(PROJECTION_PHONE, wrap);            return new MergeCursor(new Cursor[] { translated, phoneCursor });        } else {            return phoneCursor;        }    }
查询用户输入相关的联系人,然后绑定view
    @Override    public final void bindView(View view, Context context, Cursor cursor) {        TextView name = (TextView) view.findViewById(R.id.name);        name.setText(cursor.getString(NAME_INDEX));        TextView label = (TextView) view.findViewById(R.id.label);        int type = cursor.getInt(TYPE_INDEX);        CharSequence labelText = Phone.getDisplayLabel(mContext, type,                cursor.getString(LABEL_INDEX));        if (labelText.length() == 0 ||                (labelText.length() == 1 && labelText.charAt(0) == '\u00A0')) {            label.setVisibility(View.GONE);        } else {            label.setText(labelText);            label.setVisibility(View.VISIBLE);        }        TextView number = (TextView) view.findViewById(R.id.number);        number.setText(cursor.getString(NUMBER_INDEX));    }
这里基本上完成了自动补全的功能,具体细节大家可以看看具体代码。

2.3 添加联系人button处理

添加联系人button处理,查看对应监听器代码
      if (v == mAddRecipientButton) {        if (recipientCount() < recipientLimit) {Intent intent = new Intent(ACTION_MULTI_PICK,Contacts.CONTENT_URI);startActivityForResult(intent, REQUEST_CODE_PICK_CONTACT);} else {checkAddTooManyRceiver(recipientCount());}        }
这里做了一个联系人数量的检查,当然正常情况会跳转到联系人界面选择添加的联系人,至于联系人这个app怎么做的这里不做太多的分析。那添加过后联系人的信息就会返回给当前界面,在onActivitiyResult方法里做的处理。这里简单分析该方法对联系人信息的处理;
case REQUEST_CODE_PICK_CONTACT:                Bundle b = data.getExtras();                Bundle contactSet = b.getBundle("result");                Set<String> set = contactSet.keySet();                Iterator<String> i = set.iterator();                if (mRecipientsEditor != null) {    addRecipientsListeners();    ContactList list = mRecipientsEditor    .constructContactsFromInput();    int add_count = 0;    if (list.size() + set.size() > recipientLimit) {    checkAddTooManyRceiver(list.size() + set.size());    add_count = recipientLimit - list.size();    } else {    add_count = set.size();    }    int flag = 0;    while (i.hasNext()) {    if (flag < add_count) {    String key = i.next();    list.add(Contact.get(    contactSet.getStringArray(key)[NUMBER_INDEX],    false));    flag++;    } else {    break;    }    }    mRecipientsEditor.populate(list);    }                break;
这里做的很简单通过返回的联系人信息同步到ui上,populate方法做这件事情
    public void populate(ContactList list) {        SpannableStringBuilder sb = new SpannableStringBuilder();        for (Contact c : list) {            if (sb.length() != 0) {                sb.append(", ");            }            sb.append(contactToToken(c));        }        setText(sb);    }

3、总结

接收者ui其操作很简单,就是显示联系人或者提供给用户编辑联系人。







更多相关文章

  1. Android(安卓)Activity 和 Task 设计指导
  2. Android文档学习03_Intent
  3. Android学习 之 应用程序基础及四大组件
  4. Android基础笔记(九)- 广播
  5. 一个公开了源码的Android(安卓)UI 设计器,很好很强大,不知道的可以
  6. Android(安卓)Phonebook编写联系人UI加载及联系人保存流程(一)
  7. android 获取上一个activity的返回值
  8. Android活动文件夹
  9. Android实现自定义listview上拉刷新下拉加载以及侧滑编辑、删除

随机推荐

  1. Android中的13种Drawable小结
  2. Android进阶(十)Android(安卓)发邮件
  3. Android虚拟平台的编译和整合
  4. android中的资源,资源与xml文件
  5. 使用android快速开发框架afinal 开发andr
  6. Android(安卓)基础总结:(二)Android(安卓)AP
  7. 用fastboot大刷Android(安卓)~换个方法刷
  8. android待机详细结合代码分析(二)
  9. IOS和Android(安卓)OpenGL游戏引擎的集成
  10. Android(安卓)核心分析(12) -----Android