短信ui--会话编辑界面(三)历史记录

会话编辑界面(三)历史记录

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做了一个简单的介绍,至于其中一些具体的小细节,可以看一下代码就明白了。




  

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值