簡訊ui–會話編輯介面(三)記錄

來源:互聯網
上載者:User
會話編輯介面(三)記錄 1、前言       前文對接收者ui有一個簡單的瞭解,下面來看看簡訊記錄的載入以及介面更新。例如當我們發送一條簡訊,介面上顯示“正在發送”,發送完後變成“已發送”,以及接收的簡訊時顯示接收時間等等功能,只所以用單獨的篇幅來講解,主要考慮到該ui的重要性。2、功能分析2.1 初始化      簡訊記錄介面的初始仍然是在ComposeMessageActivity的onCreate方法中通過調用initMessageList方法:
    private void initMessageList() {        if (mMsgListAdapter != null) {            return;        }        String highlightString = getIntent().getStringExtra("highlight");        Pattern highlight = highlightString == null            ? null            : Pattern.compile("\\b" + Pattern.quote(highlightString), Pattern.CASE_INSENSITIVE);        // Initialize the list adapter with a null cursor.        mMsgListAdapter = new MessageListAdapter(this, null, mMsgListView, true, highlight);        mMsgListAdapter.setOnDataSetChangedListener(mDataSetChangedListener);        mMsgListAdapter.setMsgListItemHandler(mMessageListItemHandler);        mMsgListView.setAdapter(mMsgListAdapter);        mMsgListView.setItemsCanFocus(false);        mMsgListView.setVisibility(View.VISIBLE);        mMsgListView.setOnCreateContextMenuListener(mMsgListMenuCreateListener);        mMsgListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {                if (view != null) {                    ((MessageListItem) view).onMessageListItemClick();                }            }        });    }

該方法初始化用於顯示歷程清單地的Listview,以及用於填充listView的adapter,並設定監聽器和長按menu。

2.2  UI分析2.2.1 UI 簡介       下面就來看看這個記錄是什麼樣的,有哪些介面元素組成,來初步認識一下這個介面。為簡訊記錄的ui,
記錄從可以看出記錄的ui至少包含以下ui組件:連絡人頭像、連絡人號碼或者姓名、內容、接收和發送時間,如果是多媒體訊息有對應附件、主題的顯示。當然除了這些還有一些錯誤顯示ui等等。2.2.2 ui布局分析   要窺探該介面怎麼布局,首先來看看MessageListAdapter類是如何綁定ui的?該類有兩個重要的方法來完成ui和資料的綁定bindView、newView;其中newView用於載入布局檔案,定義一個簡訊ui,bindview用於將從簡訊資料庫擷取的資料設定到newView上的ui上。這裡來看看系統怎麼定義這個ui的
    @Override    public View newView(Context context, Cursor cursor, ViewGroup parent) {        return mInflater.inflate(R.layout.message_list_item, parent, false);    }

那該ui定義在布局檔案裡面,這裡簡短閑扯android ui的高明,之前有做過J2ME開發的同學可能對android的xml布局印象深刻,估計有很多同學疑問了J2ME為啥不引進這個xml布局,J2ME的ui實現完全靠一行一行的代碼,且複雜冗長,一言難盡哈。這裡來看看神秘的布局檔案。

<com.android.mms.ui.MessageListItem    xmlns:android="http://schemas.android.com/apk/res/android"    android:id="@+id/msg_list_item"    android:layout_width="match_parent"    android:layout_height="wrap_content"    android:background="@drawable/listitem_background"    android:orientation="horizontal">    <LinearLayout android:id="@+id/mms_layout_view_parent"        android:paddingLeft="5dip"        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:layout_weight="1"        android:orientation="vertical" >        <ViewStub android:id="@+id/mms_layout_view_stub"            android:layout="@layout/mms_layout_view"         mms 附件ui,其還有自己的布局檔案,大家都可以查看多媒體訊息附件的ui,該ui包含一個iamgeview            android:layout_width="match_parent"              另外就是一個playbutton               android:layout_height="wrap_content"/>        <RelativeLayout            android:layout_width="match_parent"            android:layout_height="wrap_content">            <android.widget.QuickContactBadge                android:layout_marginLeft="0dip"                android:layout_marginRight="5dip"                android:layout_marginTop="5dip"                              android:layout_marginBottom="5dip"                android:id="@+id/avatar"                style="?android:attr/quickContactBadgeStyleWindowSmall" /> 用於顯示連絡人表徵圖            <View                android:layout_width="match_parent"                android:layout_height="0dip"                android:layout_below="@id/avatar" />            <LinearLayout android:id="@+id/status_icons"                android:layout_width="wrap_content"                android:layout_height="wrap_content"                android:layout_alignBottom="@id/text_view"         簡訊內容包含、主題、時間                android:layout_alignParentRight="true"                android:layout_marginBottom="8dip"                android:orientation="horizontal" >                <ImageView                    android:id="@+id/locked_indicator"                    android:layout_width="wrap_content"                    android:layout_height="wrap_content"                    android:src="@drawable/ic_lock_message_sms"    鎖定簡訊的image,鎖的表徵圖,該功能就是當你鎖定一條簡訊後,刪除該會話,該會話的                    android:paddingRight="3dip"                    其他簡訊都刪除,但是加鎖的簡訊不被刪除,這樣可以防止誤刪                    android:visibility="gone" />                <ImageView                    android:id="@+id/delivered_indicator"                                 android:layout_width="wrap_content"                    android:layout_height="wrap_content"          簡訊傳送報告,有可能是fail的表徵圖、以及開啟傳送報告後有一個傳送表徵圖                    android:paddingRight="3dip"                    android:visibility="gone" />                <ImageView                    android:id="@+id/details_indicator"                    android:layout_width="wrap_content"            暫時不清楚                    android:layout_height="wrap_content"                                android:src="@drawable/ic_sms_mms_details"                    android:visibility="gone" />                </LinearLayout>            </RelativeLayout>        </LinearLayout>    <ViewStub android:id="@+id/mms_downloading_view_stub"        android:layout="@layout/mms_downloading_view"          如果多媒體訊息未下載會顯示該ui,該ui有一個下載button,一個textview,當點擊button        android:layout_gravity="center_vertical"               狀態更新為正在下載        android:layout_width="wrap_content"        android:layout_height="wrap_content"/></com.android.mms.ui.MessageListItem>

基本上一條短多媒體訊息包含的ui就是上述,會根據當前短多媒體訊息的狀態來設定來設定對應UI 的值,顯示給使用者,至於如何設定,下回分解。2.2.3  資料的綁定綁定資料bindView方法來實現,核心的代碼如下

    @Override    public void bindView(View view, Context context, Cursor cursor) {        if (view instanceof MessageListItem) {            String type = cursor.getString(mColumnsMap.mColumnMsgType);            long msgId = cursor.getLong(mColumnsMap.mColumnMsgId);            MessageItem msgItem = getCachedMessageItem(type, msgId, cursor);            if (msgItem != null) {                MessageListItem mli = (MessageListItem) view;                MessageItem oldMessageItem = mli.getMessageItem();                if (oldMessageItem != null) {                    String oldAddress = oldMessageItem.mAddress;                    if (oldAddress != null) {                        HashSet<MessageListItem> set = mAddressToMessageListItems.get(oldAddress);                        if (set != null) {                            set.remove(mli);                        }                    }                }                mli.bind(mAvatarCache, msgItem); 重要
上面的代碼做的事情很簡單,將查詢到的簡訊綁定到ui,這裡的綁定涉藉助於MessageListItem的bind方法。對於每個欄位怎麼設定的這裡不做解析,有興趣的大家可以看看代碼,很簡單。2.4 長按按鈕對於每條簡訊,這裡給他們設定了一個長按事件,給使用者提供了以下功能。這裡沒有完全顯示,但我們可以通過代碼知道其具體有哪些功能。mMsgListMenuCreateListener該變數用於建立menu,menu的監聽的監聽事件處理MsgListMenuClickListener來完成。以下代碼是對每個menu的處理
    private final class MsgListMenuClickListener implements MenuItem.OnMenuItemClickListener {        public boolean onMenuItemClick(MenuItem item) {            if (!isCursorValid()) {                return false;            }            Cursor cursor = mMsgListAdapter.getCursor();            String type = cursor.getString(COLUMN_MSG_TYPE);            long msgId = cursor.getLong(COLUMN_ID);            MessageItem msgItem = getMessageItem(type, msgId, true);            if (msgItem == null) {                return false;            }            switch (item.getItemId()) {                case MENU_EDIT_MESSAGE:       編輯簡訊                    editMessageItem(msgItem);                    drawBottomPanel();                    return true;                case MENU_COPY_MESSAGE_TEXT:  複製簡訊文本                    copyToClipboard(msgItem.mBody);                    return true;                case MENU_FORWARD_MESSAGE:     轉寄簡訊                    forwardMessage(msgItem);                    return true;                case MENU_VIEW_SLIDESHOW:     查看投影片                    MessageUtils.viewMmsMessageAttachment(ComposeMessageActivity.this,                            ContentUris.withAppendedId(Mms.CONTENT_URI, msgId), null);                    return true;                case MENU_VIEW_MESSAGE_DETAILS: { 查看簡訊資訊:包含簡訊大小、發送和接收的時間                    String messageDetails = MessageUtils.getMessageDetails(                            ComposeMessageActivity.this, cursor, msgItem.mMessageSize);                    new AlertDialog.Builder(ComposeMessageActivity.this)                            .setTitle(R.string.message_details_title)                            .setMessage(messageDetails)                            .setPositiveButton(android.R.string.ok, null)                            .setCancelable(true)                            .show();                    return true;                }                case MENU_DELETE_MESSAGE: {刪除簡訊                    DeleteMessageListener l = new DeleteMessageListener(                            msgItem.mMessageUri, msgItem.mLocked);                    confirmDeleteDialog(l, msgItem.mLocked);                    return true;                }                case MENU_DELIVERY_REPORT: 簡訊傳送報告                    showDeliveryReport(msgId, type);                    return true;                case MENU_COPY_TO_SDCARD: { 複製簡訊到sdcard                    String successMessage = getResources().getString(R.string.copy_to_sdcard_success, SAVED_ATTACHMENT_DIR);                    String resultMessage = copyMedia(msgId) ? successMessage : getResources()                            .getString(R.string.copy_to_sdcard_fail);                    Toast.makeText(ComposeMessageActivity.this, resultMessage, Toast.LENGTH_SHORT).show();                    return true;                }                case MENU_COPY_TO_DRM_PROVIDER: {                    int resId = getDrmMimeSavedStringRsrc(msgId, copyToDrmProvider(msgId));                    Toast.makeText(ComposeMessageActivity.this, resId, Toast.LENGTH_SHORT).show();                    return true;                }                case MENU_LOCK_MESSAGE: {  鎖簡訊                    lockMessage(msgItem, true);                    return true;                }                case MENU_UNLOCK_MESSAGE: {解鎖                    lockMessage(msgItem, false);                    return true;                }                case MENU_COPY_TO_SIM: { 複製簡訊到sim卡                    if (hasIccCardCount() > 1) {                        String[] items = new String[TelephonyManager.getPhoneCount()];                        for (int i = 0; i < items.length; i++) {                            items[i] = getMultiSimName(i);                        }                        CopyToSimSelectListener listener = new CopyToSimSelectListener(msgItem);                        new AlertDialog.Builder(ComposeMessageActivity.this)                            .setTitle(R.string.copy_to_sim)                            .setIcon(android.R.drawable.ic_dialog_info)                            .setPositiveButton(android.R.string.ok, listener)                            .setSingleChoiceItems(items, 0, listener)                            .setCancelable(true)                            .show();                    } else {                        copyToSimWithToast(msgItem);                    }                    return true;                }                default:                    return false;            }        }    }
3、總結
   這裡對該ui做了一個簡單的介紹,至於其中一些具體的小細節,可以看一下代碼就明白了。



  

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.