summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--res/values/ids.xml19
-rw-r--r--src/com/android/mail/browse/ConversationContainer.java71
-rw-r--r--src/com/android/mail/browse/ConversationViewAdapter.java15
-rw-r--r--src/com/android/mail/browse/MessageHeaderView.java132
-rw-r--r--src/com/android/mail/ui/ConversationViewFragment.java8
-rw-r--r--tests/src/com/android/mail/browse/MessageHeaderViewTest.java8
6 files changed, 133 insertions, 120 deletions
diff --git a/res/values/ids.xml b/res/values/ids.xml
deleted file mode 100644
index b2d77dbb7..000000000
--- a/res/values/ids.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2012 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-
-<resources>
- <item type="id" name="view_tag_conversation_index" />
-</resources>
diff --git a/src/com/android/mail/browse/ConversationContainer.java b/src/com/android/mail/browse/ConversationContainer.java
index e563bdd87..531d31c41 100644
--- a/src/com/android/mail/browse/ConversationContainer.java
+++ b/src/com/android/mail/browse/ConversationContainer.java
@@ -19,6 +19,7 @@ package com.android.mail.browse;
import android.content.Context;
import android.util.AttributeSet;
+import android.util.SparseArray;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewConfiguration;
@@ -33,9 +34,6 @@ import com.android.mail.browse.ConversationViewAdapter.ConversationItem;
import com.android.mail.browse.ScrollNotifier.ScrollListener;
import com.android.mail.utils.DequeMap;
import com.android.mail.utils.LogUtils;
-import com.google.common.collect.Sets;
-
-import java.util.Set;
/**
* A specialized ViewGroup container for conversation view. It is designed to contain a single
@@ -112,16 +110,16 @@ public class ConversationContainer extends ViewGroup implements ScrollListener {
private final DequeMap<Integer, View> mScrapViews = new DequeMap<Integer, View>();
/**
- * The set of children queued for later removal by a Runnable posted to the UI thread (no
- * synchronization required). Scroll changes cause children to be added to this set, and the
- * Runnable later removes the children when it safely detaches them outside of a
- * draw/getDisplayList operation.
+ * The current set of overlay views in the view hierarchy. Looking through this map is faster
+ * than traversing the view hierarchy.
* <p>
* WebView sometimes notifies of scroll changes during a draw (or display list generation), when
* it's not safe to detach view children because ViewGroup is in the middle of iterating over
- * its child array.
+ * its child array. So we remove any child from this list immediately and queue up a task to
+ * detach it later. Since nobody other than the detach task references that view in the
+ * meantime, we don't need any further checks or synchronization.
*/
- private final Set<View> mChildrenToRemove;
+ private final SparseArray<View> mOverlayViews;
private final float mDensity;
@@ -129,8 +127,6 @@ public class ConversationContainer extends ViewGroup implements ScrollListener {
private boolean mDisableLayoutTracing;
- private static final int VIEW_TAG_CONVERSATION_INDEX = R.id.view_tag_conversation_index;
-
/**
* Child views of this container should implement this interface to be notified when they are
* being detached.
@@ -151,7 +147,7 @@ public class ConversationContainer extends ViewGroup implements ScrollListener {
public ConversationContainer(Context c, AttributeSet attrs) {
super(c, attrs);
- mChildrenToRemove = Sets.newHashSet();
+ mOverlayViews = new SparseArray<View>();
mDensity = c.getResources().getDisplayMetrics().density;
mScale = mDensity;
@@ -182,14 +178,6 @@ public class ConversationContainer extends ViewGroup implements ScrollListener {
return mOverlayAdapter;
}
- private int getOverlayCount() {
- return Math.max(0, getChildCount() - 1);
- }
-
- private View getOverlayAt(int i) {
- return getChildAt(i + 1);
- }
-
private void forwardFakeMotionEvent(MotionEvent original, int newAction) {
MotionEvent newEvent = MotionEvent.obtain(original);
newEvent.setAction(newAction);
@@ -372,18 +360,14 @@ public class ConversationContainer extends ViewGroup implements ScrollListener {
child.measure(childWidthSpec, childHeightSpec);
}
- private void onOverlayScrolledOff(final View overlayView, final int itemType,
- int overlayTop, int overlayBottom) {
- // do it asynchronously, as scroll notification can happen during a draw, when it's not
- // safe to remove children
+ private void onOverlayScrolledOff(final int adapterIndex, final View overlayView,
+ final int itemType, int overlayTop, int overlayBottom) {
+ // detach the view asynchronously, as scroll notification can happen during a draw, when
+ // it's not safe to remove children
- // ensure that repeated scroll events that want to remove the same header only do it
- // once
- if (mChildrenToRemove.contains(overlayView)) {
- return;
- }
+ // but immediately remove this view from the view set so future lookups don't find it
+ mOverlayViews.remove(adapterIndex);
- mChildrenToRemove.add(overlayView);
post(new Runnable() {
@Override
public void run() {
@@ -407,7 +391,6 @@ public class ConversationContainer extends ViewGroup implements ScrollListener {
private void detachOverlay(View overlayView, int itemType) {
detachViewFromParent(overlayView);
mScrapViews.add(itemType, overlayView);
- mChildrenToRemove.remove(overlayView);
if (overlayView instanceof DetachListener) {
((DetachListener) overlayView).onDetachedFromParent();
}
@@ -461,7 +444,7 @@ public class ConversationContainer extends ViewGroup implements ScrollListener {
}
private void positionOverlay(int adapterIndex, int overlayTopY, int overlayBottomY) {
- View overlayView = findExistingOverlayView(adapterIndex);
+ View overlayView = mOverlayViews.get(adapterIndex);
final ConversationItem item = mOverlayAdapter.getItem(adapterIndex);
// is the overlay visible and does it have non-zero height?
@@ -484,22 +467,19 @@ public class ConversationContainer extends ViewGroup implements ScrollListener {
}
traceLayout("laying out overlay %d with h=%d", adapterIndex,
overlayView.getMeasuredHeight());
- layoutOverlay(overlayView, overlayTopY);
+ layoutOverlay(overlayView, overlayTopY, overlayTopY + overlayView.getMeasuredHeight());
} else {
// hide overlay
if (overlayView != null) {
traceLayout("hide overlay %d", adapterIndex);
- onOverlayScrolledOff(overlayView, item.getType(), overlayTopY, overlayBottomY);
+ onOverlayScrolledOff(adapterIndex, overlayView, item.getType(), overlayTopY,
+ overlayBottomY);
} else {
traceLayout("ignore non-visible overlay %d", adapterIndex);
}
}
}
- private void layoutOverlay(View child, int childTop) {
- layoutOverlay(child, childTop, childTop + child.getMeasuredHeight());
- }
-
// layout an existing view
// need its top offset into the conversation, its height, and the scroll offset
private void layoutOverlay(View child, int childTop, int childBottom) {
@@ -513,7 +493,7 @@ public class ConversationContainer extends ViewGroup implements ScrollListener {
final View convertView = mScrapViews.poll(itemType);
View view = mOverlayAdapter.getView(adapterIndex, convertView, this);
- view.setTag(VIEW_TAG_CONVERSATION_INDEX, adapterIndex);
+ mOverlayViews.put(adapterIndex, view);
// Only re-attach if the view had previously been added to a view hierarchy.
// Since external components can contribute to the scrap heap (addScrapView), we can't
@@ -530,19 +510,6 @@ public class ConversationContainer extends ViewGroup implements ScrollListener {
return view;
}
- private View findExistingOverlayView(int adapterIndex) {
- for (int i = 0, count = getOverlayCount(); i < count; i++) {
- final View overlay = getOverlayAt(i);
- final Integer tag = (Integer) overlay.getTag(VIEW_TAG_CONVERSATION_INDEX);
- // ignore children queued to be removed
- // otherwise we'll re-use and lay out this view and then just throw it away
- if (tag != null && tag == adapterIndex && !mChildrenToRemove.contains(overlay)) {
- return overlay;
- }
- }
- return null;
- }
-
/**
* Prevents any layouts from happening until the next time {@link #onGeometryChange(int[])} is
* called. Useful when you know the HTML spacer coordinates are inconsistent with adapter items.
diff --git a/src/com/android/mail/browse/ConversationViewAdapter.java b/src/com/android/mail/browse/ConversationViewAdapter.java
index 2d09d22fe..686262294 100644
--- a/src/com/android/mail/browse/ConversationViewAdapter.java
+++ b/src/com/android/mail/browse/ConversationViewAdapter.java
@@ -31,6 +31,7 @@ import com.android.mail.R;
import com.android.mail.browse.ConversationViewHeader.ConversationViewHeaderCallbacks;
import com.android.mail.browse.MessageHeaderView.MessageHeaderViewCallbacks;
import com.android.mail.providers.Account;
+import com.android.mail.providers.Address;
import com.android.mail.providers.Conversation;
import com.android.mail.providers.Message;
import com.android.mail.providers.UIProvider;
@@ -38,6 +39,7 @@ import com.android.mail.utils.LogUtils;
import com.google.common.collect.Lists;
import java.util.List;
+import java.util.Map;
/**
* A specialized adapter that contains overlay views to draw on top of the underlying conversation
@@ -58,6 +60,7 @@ public class ConversationViewAdapter extends BaseAdapter {
private final LoaderManager mLoaderManager;
private final MessageHeaderViewCallbacks mMessageCallbacks;
private ConversationViewHeaderCallbacks mConversationCallbacks;
+ private Map<String, Address> mAddressCache;
private final LayoutInflater mInflater;
private boolean mDefaultReplyAll;
@@ -171,9 +174,16 @@ public class ConversationViewAdapter extends BaseAdapter {
public class MessageHeaderItem extends ConversationItem {
public final Message message;
+
+ // view state variables
private boolean mExpanded;
public boolean detailsExpanded;
+ // cached values to speed up re-rendering during view recycling
+ public CharSequence timestampShort;
+ public CharSequence timestampLong;
+ public CharSequence recipientSummaryText;
+
private MessageHeaderItem(Message message, boolean expanded) {
this.message = message;
mExpanded = expanded;
@@ -190,7 +200,7 @@ public class ConversationViewAdapter extends BaseAdapter {
public View createView(Context context, LayoutInflater inflater, ViewGroup parent) {
final MessageHeaderView v = (MessageHeaderView) inflater.inflate(
R.layout.conversation_message_header, parent, false);
- v.initialize(mDateBuilder, mAccount);
+ v.initialize(mDateBuilder, mAccount, mAddressCache);
v.setCallbacks(mMessageCallbacks);
return v;
}
@@ -265,13 +275,14 @@ public class ConversationViewAdapter extends BaseAdapter {
public ConversationViewAdapter(Context context, Account account, LoaderManager loaderManager,
MessageHeaderViewCallbacks messageCallbacks,
- ConversationViewHeaderCallbacks convCallbacks) {
+ ConversationViewHeaderCallbacks convCallbacks, Map<String, Address> addressCache) {
mContext = context;
mDateBuilder = new FormattedDateBuilder(context);
mAccount = account;
mLoaderManager = loaderManager;
mMessageCallbacks = messageCallbacks;
mConversationCallbacks = convCallbacks;
+ mAddressCache = addressCache;
mInflater = LayoutInflater.from(context);
mItems = Lists.newArrayList();
diff --git a/src/com/android/mail/browse/MessageHeaderView.java b/src/com/android/mail/browse/MessageHeaderView.java
index d9c325997..c39bdeea7 100644
--- a/src/com/android/mail/browse/MessageHeaderView.java
+++ b/src/com/android/mail/browse/MessageHeaderView.java
@@ -56,6 +56,7 @@ import com.google.common.annotations.VisibleForTesting;
import java.io.IOException;
import java.io.StringReader;
+import java.util.Map;
public class MessageHeaderView extends LinearLayout implements OnClickListener,
OnMenuItemClickListener, HeaderBlock {
@@ -94,6 +95,15 @@ public class MessageHeaderView extends LinearLayout implements OnClickListener,
private ViewGroup mImagePromptView;
private View mBottomBorderView;
private ImageView mPresenceView;
+ private View mPhotoSpacerView;
+ private View mForwardButton;
+ private View mOverflowButton;
+ private View mDraftIcon;
+ private View mEditDraftButton;
+ private TextView mUpperDateView;
+ private View mReplyButton;
+ private View mReplyAllButton;
+ private View mAttachmentIcon;
// temporary fields to reference raw data between initial render and details
// expansion
@@ -108,8 +118,6 @@ public class MessageHeaderView extends LinearLayout implements OnClickListener,
private boolean mIsSending;
- private boolean mDetailsExpanded;
-
/**
* The snappy header has special visibility rules (i.e. no details header,
* even though it has an expanded appearance)
@@ -126,6 +134,8 @@ public class MessageHeaderView extends LinearLayout implements OnClickListener,
private Account mAccount;
+ private Map<String, Address> mAddressCache;
+
private boolean mShowImagePrompt;
private boolean mDefaultReplyAll;
@@ -190,9 +200,18 @@ public class MessageHeaderView extends LinearLayout implements OnClickListener,
mSenderNameView = (TextView) findViewById(R.id.sender_name);
mSenderEmailView = (TextView) findViewById(R.id.sender_email);
mPhotoView = (QuickContactBadge) findViewById(R.id.photo);
+ mPhotoSpacerView = findViewById(R.id.photo_spacer);
+ mReplyButton = findViewById(R.id.reply);
+ mReplyAllButton = findViewById(R.id.reply_all);
+ mForwardButton = findViewById(R.id.forward);
mStarView = (ImageView) findViewById(R.id.star);
mPresenceView = (ImageView) findViewById(R.id.presence);
mTitleContainerView = (ViewGroup) findViewById(R.id.title_container);
+ mOverflowButton = findViewById(R.id.overflow);
+ mDraftIcon = findViewById(R.id.draft);
+ mEditDraftButton = findViewById(R.id.edit_draft);
+ mUpperDateView = (TextView) findViewById(R.id.upper_date);
+ mAttachmentIcon = findViewById(R.id.attachment);
mCollapsedStarVis = mStarView.getVisibility();
mTitleContainerCollapsedMarginRight = ((MarginLayoutParams) mTitleContainerView
@@ -302,9 +321,11 @@ public class MessageHeaderView extends LinearLayout implements OnClickListener,
updateChildVisibility();
}
- public void initialize(FormattedDateBuilder dateBuilder, Account account) {
+ public void initialize(FormattedDateBuilder dateBuilder, Account account,
+ Map<String, Address> addressCache) {
mDateBuilder = dateBuilder;
mAccount = account;
+ mAddressCache = addressCache;
}
public void bind(MessageHeaderItem headerItem, boolean defaultReplyAll) {
@@ -321,8 +342,10 @@ public class MessageHeaderView extends LinearLayout implements OnClickListener,
setExpanded(headerItem.isExpanded());
mTimestampMs = mMessage.dateReceivedMs;
- if (mDateBuilder != null) {
+ mTimestampShort = headerItem.timestampShort;
+ if (mTimestampShort == null) {
mTimestampShort = mDateBuilder.formatShortDate(mTimestampMs);
+ headerItem.timestampShort = mTimestampShort;
}
mTo = mMessage.getToAddresses();
@@ -357,14 +380,13 @@ public class MessageHeaderView extends LinearLayout implements OnClickListener,
if (TextUtils.isEmpty(from)) {
from = mAccount.name;
}
- mSender = Address.getEmailAddress(from);
+ mSender = getAddress(from);
mSenderNameView.setText(getHeaderTitle());
mSenderEmailView.setText(getHeaderSubtitle());
- TextView upperDateView = (TextView) findViewById(R.id.upper_date);
- if (upperDateView != null) {
- upperDateView.setText(mTimestampShort);
+ if (mUpperDateView != null) {
+ mUpperDateView.setText(mTimestampShort);
}
mStarView.setSelected(mMessage.starred);
@@ -376,6 +398,24 @@ public class MessageHeaderView extends LinearLayout implements OnClickListener,
t.pause(HEADER_RENDER_TAG);
}
+ private Address getAddress(String emailStr) {
+ return getAddress(mAddressCache, emailStr);
+ }
+
+ private static Address getAddress(Map<String, Address> cache, String emailStr) {
+ Address addr = null;
+ if (cache != null) {
+ addr = cache.get(emailStr);
+ }
+ if (addr == null) {
+ addr = Address.getEmailAddress(emailStr);
+ if (cache != null) {
+ cache.put(emailStr, addr);
+ }
+ }
+ return addr;
+ }
+
private boolean isInOutbox() {
// TODO: what should this read? Folder info?
return false;
@@ -430,8 +470,8 @@ public class MessageHeaderView extends LinearLayout implements OnClickListener,
* Return the name, if known, or just the address.
*/
private static CharSequence getSenderName(Address sender) {
- String displayName = sender == null ? "" : sender.getName();
- return TextUtils.isEmpty(displayName) && sender != null ? sender.getAddress() : displayName;
+ final String displayName = sender.getName();
+ return TextUtils.isEmpty(displayName) ? sender.getAddress() : displayName;
}
/**
@@ -442,9 +482,8 @@ public class MessageHeaderView extends LinearLayout implements OnClickListener,
return TextUtils.isEmpty(displayName) ? null : sender.getAddress();
}
- private void setChildVisibility(int visibility, int... resources) {
- for (int res : resources) {
- View v = findViewById(res);
+ private void setChildVisibility(int visibility, View... children) {
+ for (View v : children) {
if (v != null) {
v.setVisibility(visibility);
}
@@ -481,38 +520,39 @@ public class MessageHeaderView extends LinearLayout implements OnClickListener,
}
setReplyOrReplyAllVisible();
- setChildVisibility(normalVis, R.id.photo, R.id.photo_spacer, R.id.forward,
- R.id.sender_email, R.id.overflow);
- setChildVisibility(draftVis, R.id.draft, R.id.edit_draft);
- setChildVisibility(GONE, R.id.attachment, R.id.upper_date);
- setChildVisibility(VISIBLE, R.id.star);
+ setChildVisibility(normalVis, mPhotoView, mPhotoSpacerView, mForwardButton,
+ mSenderEmailView, mOverflowButton);
+ setChildVisibility(draftVis, mDraftIcon, mEditDraftButton);
+ setChildVisibility(GONE, mAttachmentIcon, mUpperDateView);
+ setChildVisibility(VISIBLE, mStarView);
setChildMarginRight(mTitleContainerView, 0);
} else {
setMessageDetailsVisibility(GONE);
- setChildVisibility(VISIBLE, R.id.sender_email, R.id.upper_date);
+ setChildVisibility(VISIBLE, mSenderEmailView, mUpperDateView);
- setChildVisibility(GONE, R.id.edit_draft, R.id.reply, R.id.reply_all, R.id.forward);
- setChildVisibility(GONE, R.id.overflow);
+ setChildVisibility(GONE, mEditDraftButton, mReplyButton, mReplyAllButton,
+ mForwardButton);
+ setChildVisibility(GONE, mOverflowButton);
setChildVisibility(mMessage.hasAttachments ? VISIBLE : GONE,
- R.id.attachment);
+ mAttachmentIcon);
- setChildVisibility(mCollapsedStarVis, R.id.star);
+ setChildVisibility(mCollapsedStarVis, mStarView);
setChildMarginRight(mTitleContainerView, mTitleContainerCollapsedMarginRight);
if (mIsDraft) {
- setChildVisibility(VISIBLE, R.id.draft);
- setChildVisibility(GONE, R.id.photo, R.id.photo_spacer);
+ setChildVisibility(VISIBLE, mDraftIcon);
+ setChildVisibility(GONE, mPhotoView, mPhotoSpacerView);
} else {
- setChildVisibility(GONE, R.id.draft);
- setChildVisibility(VISIBLE, R.id.photo, R.id.photo_spacer);
+ setChildVisibility(GONE, mDraftIcon);
+ setChildVisibility(VISIBLE, mPhotoView, mPhotoSpacerView);
}
}
@@ -528,15 +568,15 @@ public class MessageHeaderView extends LinearLayout implements OnClickListener,
*/
private void setReplyOrReplyAllVisible() {
if (mIsDraft) {
- setChildVisibility(GONE, R.id.reply, R.id.reply_all);
+ setChildVisibility(GONE, mReplyButton, mReplyAllButton);
return;
- } else if (findViewById(R.id.overflow) == null) {
- setChildVisibility(VISIBLE, R.id.reply, R.id.reply_all);
+ } else if (mOverflowButton == null) {
+ setChildVisibility(VISIBLE, mReplyButton, mReplyAllButton);
return;
}
- setChildVisibility(mDefaultReplyAll ? GONE : VISIBLE, R.id.reply);
- setChildVisibility(mDefaultReplyAll ? VISIBLE : GONE, R.id.reply_all);
+ setChildVisibility(mDefaultReplyAll ? GONE : VISIBLE, mReplyButton);
+ setChildVisibility(mDefaultReplyAll ? VISIBLE : GONE, mReplyAllButton);
}
private static void setChildMarginRight(View childView, int marginRight) {
@@ -551,7 +591,7 @@ public class MessageHeaderView extends LinearLayout implements OnClickListener,
}
String[] formattedEmails = new String[emails.length];
for (int i = 0; i < emails.length; i++) {
- Address e = Address.getEmailAddress(emails[i]);
+ Address e = getAddress(emails[i]);
String name = e.getName();
String addr = e.getAddress();
if (name == null || name.length() == 0) {
@@ -597,14 +637,17 @@ public class MessageHeaderView extends LinearLayout implements OnClickListener,
private final String mMe;
private final SpannableStringBuilder mBuilder = new SpannableStringBuilder();
private final CharSequence mComma;
+ private final Map<String, Address> mAddressCache;
int mRecipientCount = 0;
boolean mFirst = true;
- public RecipientListsBuilder(Context context, String me) {
+ public RecipientListsBuilder(Context context, String me,
+ Map<String, Address> addressCache) {
mContext = context;
mMe = me;
mComma = mContext.getText(R.string.enumeration_comma);
+ mAddressCache = addressCache;
}
public void append(String[] recipients, int headingRes) {
@@ -638,7 +681,7 @@ public class MessageHeaderView extends LinearLayout implements OnClickListener,
final int len = Math.min(maxToCopy, rawAddrs.length);
boolean first = true;
for (int i = 0; i < len; i++) {
- Address email = Address.getEmailAddress(rawAddrs[i]);
+ Address email = getAddress(mAddressCache, rawAddrs[i]);
String name = (mMe.equals(email.getAddress())) ? mContext.getString(R.string.me)
: email.getSimplifiedName();
@@ -662,9 +705,9 @@ public class MessageHeaderView extends LinearLayout implements OnClickListener,
@VisibleForTesting
static CharSequence getRecipientSummaryText(Context context, String me, String[] to,
- String[] cc, String[] bcc) {
+ String[] cc, String[] bcc, Map<String, Address> addressCache) {
- RecipientListsBuilder builder = new RecipientListsBuilder(context, me);
+ RecipientListsBuilder builder = new RecipientListsBuilder(context, me, addressCache);
builder.append(to, R.string.to_heading);
builder.append(cc, R.string.cc_heading);
@@ -949,8 +992,12 @@ public class MessageHeaderView extends LinearLayout implements OnClickListener,
mCollapsedDetailsView.setOnClickListener(this);
}
if (!mCollapsedDetailsValid) {
- ((TextView) findViewById(R.id.recipients_summary)).setText(getRecipientSummaryText(
- getContext(), mAccount.name, mTo, mCc, mBcc));
+ if (mMessageHeaderItem.recipientSummaryText == null) {
+ mMessageHeaderItem.recipientSummaryText = getRecipientSummaryText(getContext(),
+ mAccount.name, mTo, mCc, mBcc, mAddressCache);
+ }
+ ((TextView) findViewById(R.id.recipients_summary))
+ .setText(mMessageHeaderItem.recipientSummaryText);
((TextView) findViewById(R.id.date_summary)).setText(mTimestampShort);
@@ -975,9 +1022,10 @@ public class MessageHeaderView extends LinearLayout implements OnClickListener,
mExpandedDetailsView = (ViewGroup) v;
}
if (!mExpandedDetailsValid) {
- CharSequence longTimestamp = mDateBuilder != null ? mDateBuilder
- .formatLongDateTime(mTimestampMs) : mTimestampMs + "";
- ((TextView) findViewById(R.id.date_value)).setText(longTimestamp);
+ if (mMessageHeaderItem.timestampLong == null) {
+ mMessageHeaderItem.timestampLong = mDateBuilder.formatLongDateTime(mTimestampMs);
+ }
+ ((TextView) findViewById(R.id.date_value)).setText(mMessageHeaderItem.timestampLong);
renderEmailList(R.id.replyto_row, R.id.replyto_value, mReplyTo);
renderEmailList(R.id.to_row, R.id.to_value, mTo);
renderEmailList(R.id.cc_row, R.id.cc_value, mCc);
diff --git a/src/com/android/mail/ui/ConversationViewFragment.java b/src/com/android/mail/ui/ConversationViewFragment.java
index aa2a1bed9..a7e9145bb 100644
--- a/src/com/android/mail/ui/ConversationViewFragment.java
+++ b/src/com/android/mail/ui/ConversationViewFragment.java
@@ -54,6 +54,7 @@ import com.android.mail.browse.MessageCursor;
import com.android.mail.browse.MessageFooterView;
import com.android.mail.browse.MessageHeaderView.MessageHeaderViewCallbacks;
import com.android.mail.providers.Account;
+import com.android.mail.providers.Address;
import com.android.mail.providers.Conversation;
import com.android.mail.providers.Folder;
import com.android.mail.providers.ListParams;
@@ -63,6 +64,9 @@ import com.android.mail.providers.UIProvider.AccountCapabilities;
import com.android.mail.providers.UIProvider.FolderCapabilities;
import com.android.mail.utils.LogUtils;
import com.android.mail.utils.Utils;
+import com.google.common.collect.Maps;
+
+import java.util.Map;
/**
@@ -110,6 +114,8 @@ public final class ConversationViewFragment extends Fragment implements
private Folder mFolder;
+ private final Map<String, Address> mAddressCache = Maps.newHashMap();
+
private static final String ARG_ACCOUNT = "account";
private static final String ARG_CONVERSATION = "conversation";
private static final String ARG_FOLDER = "folder";
@@ -159,7 +165,7 @@ public final class ConversationViewFragment extends Fragment implements
mTemplates = new HtmlConversationTemplates(mContext);
mAdapter = new ConversationViewAdapter(mActivity.getActivityContext(), mAccount,
- getLoaderManager(), this, this);
+ getLoaderManager(), this, this, mAddressCache);
mConversationContainer.setOverlayAdapter(mAdapter);
mDensity = getResources().getDisplayMetrics().density;
diff --git a/tests/src/com/android/mail/browse/MessageHeaderViewTest.java b/tests/src/com/android/mail/browse/MessageHeaderViewTest.java
index 0fc8b80ed..48d7f8d9e 100644
--- a/tests/src/com/android/mail/browse/MessageHeaderViewTest.java
+++ b/tests/src/com/android/mail/browse/MessageHeaderViewTest.java
@@ -26,8 +26,8 @@ public class MessageHeaderViewTest extends AndroidTestCase {
public void testRecipientSummaryLongTo() {
String[] to = makeRecipientArray("TO", 60);
String[] cc = makeRecipientArray("CC", 60);
- String summary = MessageHeaderView.getRecipientSummaryText(getContext(), "", to, cc, null)
- .toString();
+ String summary = MessageHeaderView.getRecipientSummaryText(getContext(), "", to, cc, null,
+ null).toString();
assertTrue(summary.contains("TO00"));
assertTrue(summary.contains("TO49"));
@@ -39,8 +39,8 @@ public class MessageHeaderViewTest extends AndroidTestCase {
String[] to = makeRecipientArray("TO", 20);
String[] cc = makeRecipientArray("CC", 10);
String[] bcc = makeRecipientArray("BB", 60);
- String summary = MessageHeaderView.getRecipientSummaryText(getContext(), "", to, cc, bcc)
- .toString();
+ String summary = MessageHeaderView.getRecipientSummaryText(getContext(), "", to, cc, bcc,
+ null).toString();
assertTrue(summary.contains("TO00"));
assertTrue(summary.contains("TO19"));