diff --git a/res/values-xlarge-land/dimensions.xml b/res/values-xlarge-land/dimensions.xml index cd25e73e7..34cb239f6 100644 --- a/res/values-xlarge-land/dimensions.xml +++ b/res/values-xlarge-land/dimensions.xml @@ -23,7 +23,7 @@ - 312dip + 304dip 466dip diff --git a/res/values/dimensions.xml b/res/values/dimensions.xml index aab644a17..7038419d6 100644 --- a/res/values/dimensions.xml +++ b/res/values/dimensions.xml @@ -17,14 +17,19 @@ 100sp 16dip - 60dip - 50dip + 64dip + 64dip + 16dip + 144dip + 112dip + 10dip + 200dip + 32dip 6dip 4dip 2dip - 64dip 64dip - 72dip + 80dip 720dip 35dip 8dip diff --git a/res/values/strings.xml b/res/values/strings.xml index fc6794763..dfd6b3d6a 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -443,9 +443,9 @@ save attachment. Older - - - %1$s - %2$s + + \u0020\u2014\u0020 Account setup diff --git a/src/com/android/email/activity/MessageListItem.java b/src/com/android/email/activity/MessageListItem.java index fc882b712..d69ab18b9 100644 --- a/src/com/android/email/activity/MessageListItem.java +++ b/src/com/android/email/activity/MessageListItem.java @@ -28,11 +28,15 @@ import android.graphics.Paint.Align; import android.graphics.Paint.FontMetricsInt; import android.graphics.Typeface; import android.text.Layout.Alignment; +import android.text.Spannable; +import android.text.SpannableString; +import android.text.SpannableStringBuilder; import android.text.StaticLayout; import android.text.TextPaint; import android.text.TextUtils; import android.text.TextUtils.TruncateAt; import android.text.format.DateUtils; +import android.text.style.StyleSpan; import android.util.AttributeSet; import android.view.MotionEvent; import android.view.View; @@ -88,12 +92,15 @@ public class MessageListItem extends View { private static Bitmap sInviteIcon; private static Bitmap sFavoriteIconOff; private static Bitmap sFavoriteIconOn; - private static int sFavoriteIconLeft; + private static int sFavoriteIconWidth; private static Bitmap sSelectedIconOn; private static Bitmap sSelectedIconOff; + private static String sSubjectSnippetDivider; public String mSender; + public CharSequence mText; public String mSnippet; + public String mSubject; public boolean mRead; public long mTimestamp; public boolean mHasAttachment = false; @@ -111,8 +118,13 @@ public class MessageListItem extends View { private int mDateFaveWidth; private static int sCheckboxHitWidth; - private static int sMinimumDateWidth; + private static int sDateIconWidthWide; + private static int sDateIconWidthNarrow; private static int sFavoriteHitWidth; + private static int sFavoritePaddingRight; + private static int sSenderPaddingTopNarrow; + private static int sSenderWidth; + private static int sPaddingLarge; private static int sPaddingVerySmall; private static int sPaddingSmall; private static int sPaddingMedium; @@ -133,13 +145,23 @@ public class MessageListItem extends View { private void init(Context context) { if (!sInit) { Resources r = context.getResources(); - + sSubjectSnippetDivider = r.getString(R.string.message_list_subject_snippet_divider); sCheckboxHitWidth = r.getDimensionPixelSize(R.dimen.message_list_item_checkbox_hit_width); sFavoriteHitWidth = r.getDimensionPixelSize(R.dimen.message_list_item_favorite_hit_width); - sMinimumDateWidth = - r.getDimensionPixelSize(R.dimen.message_list_item_minimum_date_width); + sFavoritePaddingRight = + r.getDimensionPixelSize(R.dimen.message_list_item_favorite_padding_right); + sSenderPaddingTopNarrow = + r.getDimensionPixelSize(R.dimen.message_list_item_sender_padding_top_narrow); + sDateIconWidthWide = + r.getDimensionPixelSize(R.dimen.message_list_item_date_icon_width_wide); + sDateIconWidthNarrow = + r.getDimensionPixelSize(R.dimen.message_list_item_date_icon_width_narrow); + sSenderWidth = + r.getDimensionPixelSize(R.dimen.message_list_item_sender_width); + sPaddingLarge = + r.getDimensionPixelSize(R.dimen.message_list_item_padding_large); sPaddingMedium = r.getDimensionPixelSize(R.dimen.message_list_item_padding_medium); sPaddingSmall = @@ -184,8 +206,7 @@ public class MessageListItem extends View { sSelectedIconOn = BitmapFactory.decodeResource(r, R.drawable.btn_check_on_normal_holo_light); - sFavoriteIconLeft = - sFavoriteHitWidth - ((sFavoriteHitWidth - sFavoriteIconOff.getWidth()) / 2); + sFavoriteIconWidth = sFavoriteIconOff.getWidth(); sInit = true; } } @@ -205,27 +226,38 @@ public class MessageListItem extends View { } private void calculateDrawingData() { + SpannableStringBuilder ssb = new SpannableStringBuilder(); + boolean hasSubject = false; + if (!TextUtils.isEmpty(mSubject)) { + SpannableString ss = new SpannableString(mSubject); + ss.setSpan(new StyleSpan(mRead ? Typeface.NORMAL : Typeface.BOLD), 0, ss.length(), + Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); + ssb.append(ss); + hasSubject = true; + } + if (!TextUtils.isEmpty(mSnippet)) { + if (hasSubject) { + ssb.append(sSubjectSnippetDivider); + } + ssb.append(mSnippet); + } + mText = ssb; + if (mMode == MODE_WIDE) { - mDateFaveWidth = sFavoriteHitWidth + sMinimumDateWidth; + mDateFaveWidth = sFavoriteHitWidth + sDateIconWidthWide; } else { - mDateFaveWidth = sMinimumDateWidth; + mDateFaveWidth = sDateIconWidthNarrow; } mSenderSnippetWidth = mViewWidth - mDateFaveWidth - sCheckboxHitWidth; // In wide mode, we use 3/4 for snippet and 1/4 for sender mSnippetWidth = mSenderSnippetWidth; if (mMode == MODE_WIDE) { - mSnippetWidth = mSenderSnippetWidth * 3 / 4; - } - if (mHasAttachment) { - mSnippetWidth -= (sAttachmentIcon.getWidth() + sPaddingSmall); - } - if (mHasInvite) { - mSnippetWidth -= (sInviteIcon.getWidth() + sPaddingSmall); + mSnippetWidth = mSenderSnippetWidth - sSenderWidth - sPaddingLarge; } - // First, we create a StaticLayout with our snippet to get the line breaks - StaticLayout layout = new StaticLayout(mSnippet, 0, mSnippet.length(), sDefaultPaint, + // Create a StaticLayout with our snippet to get the line breaks + StaticLayout layout = new StaticLayout(mText, 0, mText.length(), sDefaultPaint, mSnippetWidth, Alignment.ALIGN_NORMAL, 1, 0, true); // Get the number of lines needed to render the whole snippet mSnippetLineCount = layout.getLineCount(); @@ -234,26 +266,26 @@ public class MessageListItem extends View { for (int i = 0; i < MAX_SUBJECT_SNIPPET_LINES; i++) { int start = layout.getLineStart(i); if (i == MAX_SUBJECT_SNIPPET_LINES - 1) { + int end = mText.length() - 1; + if (start > end) continue; // For the final line, ellipsize the text to our width - mSnippetLines[i] = TextUtils.ellipsize(mSnippet.substring(start), sDefaultPaint, + mSnippetLines[i] = TextUtils.ellipsize(mText.subSequence(start, end), sDefaultPaint, mSnippetWidth, TruncateAt.END); } else { // Just extract from start to end - mSnippetLines[i] = mSnippet.substring(start, layout.getLineEnd(i)); + mSnippetLines[i] = mText.subSequence(start, layout.getLineEnd(i)); } } // Now, format the sender for its width TextPaint senderPaint = mRead ? sDefaultPaint : sBoldPaint; - // In wide mode, we use 1/4 of the width, otherwise, the whole width - int senderWidth = (mMode == MODE_WIDE) ? mSenderSnippetWidth / 4 : mSenderSnippetWidth; + int senderWidth = (mMode == MODE_WIDE) ? sSenderWidth : mSenderSnippetWidth; // And get the ellipsized string for the calculated width - mFormattedSender = TextUtils.ellipsize(mSender, senderPaint, senderWidth - sPaddingMedium, - TruncateAt.END); + mFormattedSender = TextUtils.ellipsize(mSender, senderPaint, senderWidth, TruncateAt.END); // Get a nicely formatted date string (relative to today) String date = DateUtils.getRelativeTimeSpanString(getContext(), mTimestamp).toString(); // And make it fit to our size - mFormattedDate = TextUtils.ellipsize(date, sDatePaint, sMinimumDateWidth, TruncateAt.END); + mFormattedDate = TextUtils.ellipsize(date, sDatePaint, sDateIconWidthWide, TruncateAt.END); } @Override @@ -317,13 +349,13 @@ public class MessageListItem extends View { int senderY; if (mMode == MODE_WIDE) { - // In wide mode, we'll use 1/4 for sender and 3/4 for snippet - snippetX += mSenderSnippetWidth / 4; + // Get the right starting point for the snippet + snippetX += sSenderWidth + sPaddingLarge; // And center the sender and snippet senderY = (mViewHeight - descent - ascent) / 2; snippetY = ((mViewHeight - (2 * lineHeight)) / 2) - ascent; } else { - senderY = 20; // TODO Remove magic number + senderY = -ascent + sSenderPaddingTopNarrow; snippetY = senderY + lineHeight + sPaddingVerySmall; } @@ -346,19 +378,49 @@ public class MessageListItem extends View { mRead ? sDefaultPaint : sBoldPaint); // Draw each of the snippet lines + int subjectEnd = (mSubject == null) ? 0 : mSubject.length(); + int lineStart = 0; + TextPaint subjectPaint = mRead ? sDefaultPaint : sBoldPaint; for (int i = 0; i < MAX_SUBJECT_SNIPPET_LINES; i++) { CharSequence line = mSnippetLines[i]; + int drawX = snippetX; if (line != null) { - canvas.drawText(line, 0, line.length(), snippetX, snippetY, sDefaultPaint); + int defaultPaintStart = 0; + if (lineStart <= subjectEnd) { + int boldPaintEnd = subjectEnd - lineStart; + if (boldPaintEnd > line.length()) { + boldPaintEnd = line.length(); + } + // From 0 to end, do in bold or default depending on the read flag + canvas.drawText(line, 0, boldPaintEnd, drawX, snippetY, subjectPaint); + defaultPaintStart = boldPaintEnd; + drawX += subjectPaint.measureText(line, 0, boldPaintEnd); + } + canvas.drawText(line, defaultPaintStart, line.length(), drawX, snippetY, + sDefaultPaint); snippetY += lineHeight; + lineStart += line.length(); } } // Draw the attachment and invite icons, if necessary - int left = mSenderSnippetWidth + sCheckboxHitWidth; + int datePaddingRight; + if (mMode == MODE_WIDE) { + datePaddingRight = sFavoriteHitWidth; + } else { + datePaddingRight = sPaddingLarge; + } + int left = mViewWidth - datePaddingRight - (int)sDefaultPaint.measureText(mFormattedDate, + 0, mFormattedDate.length()) - sPaddingMedium; + if (mHasAttachment) { left -= sAttachmentIcon.getWidth() + sPaddingSmall; - int iconTop = (mViewHeight - sAttachmentIcon.getHeight()) / 2; + int iconTop; + if (mMode == MODE_WIDE) { + iconTop = (mViewHeight - sAttachmentIcon.getHeight()) / 2; + } else { + iconTop = senderY - sAttachmentIcon.getHeight(); + } canvas.drawBitmap(sAttachmentIcon, left, iconTop, sDefaultPaint); } if (mHasInvite) { @@ -368,17 +430,19 @@ public class MessageListItem extends View { } // Draw the date - int dateRight = mViewWidth - sPaddingMedium; - if (mMode == MODE_WIDE) { - dateRight -= sFavoriteHitWidth; - } - canvas.drawText(mFormattedDate, 0, mFormattedDate.length(), dateRight, senderY, sDatePaint); + canvas.drawText(mFormattedDate, 0, mFormattedDate.length(), mViewWidth - datePaddingRight, + senderY, sDatePaint); // Draw the favorite icon - int faveLeft = mViewWidth - sFavoriteIconLeft; + int faveLeft = mViewWidth - sFavoriteIconWidth; + if (mMode == MODE_WIDE) { + faveLeft -= sFavoritePaddingRight; + } else { + faveLeft -= sPaddingLarge; + } int faveTop = (mViewHeight - sFavoriteIconOff.getHeight()) / 2; if (mMode == MODE_NARROW) { - faveTop += sPaddingMedium; + faveTop += sSenderPaddingTopNarrow; } canvas.drawBitmap(mIsFavorite ? sFavoriteIconOn : sFavoriteIconOff, faveLeft, faveTop, sDefaultPaint); diff --git a/src/com/android/email/activity/MessagesAdapter.java b/src/com/android/email/activity/MessagesAdapter.java index 07717f8d8..c5a245cb4 100644 --- a/src/com/android/email/activity/MessagesAdapter.java +++ b/src/com/android/email/activity/MessagesAdapter.java @@ -17,7 +17,6 @@ package com.android.email.activity; import com.android.email.Email; -import com.android.email.R; import com.android.email.ResourceHelper; import com.android.email.Utility; import com.android.email.data.ThrottlingCursorLoader; @@ -29,7 +28,6 @@ import android.content.Context; import android.content.Loader; import android.database.Cursor; import android.os.Bundle; -import android.text.TextUtils; import android.util.Log; import android.view.View; import android.view.ViewGroup; @@ -146,23 +144,10 @@ import java.util.Set; itemView.mTimestamp = cursor.getLong(COLUMN_DATE); itemView.mSender = cursor.getString(COLUMN_DISPLAY_NAME); itemView.mSnippet = cursor.getString(COLUMN_SNIPPET); + itemView.mSubject = cursor.getString(COLUMN_SUBJECT); itemView.mSnippetLineCount = MessageListItem.NEEDS_LAYOUT; itemView.mColorChipPaint = - mShowColorChips ? mResourceHelper.getAccountColorPaint(accountId) : null; - - String text = cursor.getString(COLUMN_SUBJECT); - String snippet = cursor.getString(COLUMN_SNIPPET); - if (!TextUtils.isEmpty(snippet)) { - if (TextUtils.isEmpty(text)) { - text = snippet; - } else { - text = context.getString(R.string.message_list_snippet, text, snippet); - } - } - if (text == null) { - text = ""; - } - itemView.mSnippet = text; + mShowColorChips ? mResourceHelper.getAccountColorPaint(accountId) : null; } @Override