Pixel perfect Email widget
* Functionally correct and pixel perfect * All current assets in place Bug: 3292507 Bug: 3284201 Bug: 3135118 Bug: 3255036 Bug: 3252913 Change-Id: I8fa6752748c74b3a9789a3675da12f6c0c11975f
This commit is contained in:
parent
13c615314f
commit
0fd8ae8808
|
@ -477,7 +477,7 @@
|
|||
it exposes user passwords and other confidential information. -->
|
||||
<provider
|
||||
android:name=".provider.EmailProvider"
|
||||
android:authorities="com.android.email.provider; com.android.email.notifier"
|
||||
android:authorities="com.android.email.provider;com.android.email.notifier"
|
||||
android:multiprocess="true"
|
||||
android:permission="com.android.email.permission.ACCESS_PROVIDER"
|
||||
android:label="@string/app_name"
|
||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 854 B After Width: | Height: | Size: 696 B |
|
@ -0,0 +1,10 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (c) 2010, Google Inc. -->
|
||||
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item android:state_focused="true"
|
||||
android:drawable="@drawable/header_row_focused_email_widget_holo" />
|
||||
<item android:state_pressed="true"
|
||||
android:drawable="@drawable/header_row_press_email_widget_holo" />
|
||||
<item android:drawable="@drawable/bg_row_email_widget_holo" />
|
||||
</selector>
|
|
@ -14,56 +14,95 @@
|
|||
limitations under the License.
|
||||
-->
|
||||
|
||||
<RelativeLayout
|
||||
<LinearLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:id="@+id/widget_foo"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="fill_parent"
|
||||
android:layout_margin="5dip"
|
||||
android:background="@drawable/widget_background"
|
||||
android:orientation="vertical">
|
||||
<RelativeLayout
|
||||
android:id="@+id/widget_header"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="60dip"
|
||||
android:background="@drawable/widget_bg_top"
|
||||
android:orientation="horizontal">
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_marginTop="4dip"
|
||||
android:layout_marginBottom="20dip"
|
||||
android:layout_marginLeft="12dip"
|
||||
android:layout_marginRight="12dip"
|
||||
android:orientation="vertical"
|
||||
android:background="@drawable/gradient_bg_email_widget_holo">
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="42sp"
|
||||
android:layout_marginTop="5dip"
|
||||
android:layout_marginLeft="5dip"
|
||||
android:layout_marginRight="5dip"
|
||||
android:orientation="horizontal"
|
||||
android:paddingTop="4dip"
|
||||
android:paddingLeft="16dip"
|
||||
android:paddingRight="8dip"
|
||||
android:background="@drawable/header_bg_email_widget_holo">
|
||||
<ImageView
|
||||
android:id="@+id/widget_logo"
|
||||
android:layout_width="60dip"
|
||||
android:layout_height="60dip"
|
||||
android:layout_marginLeft="5dip"
|
||||
android:layout_marginRight="2dip"
|
||||
android:layout_marginBottom="5dip"
|
||||
android:layout_alignParentTop="true"
|
||||
android:layout_alignParentLeft="true"
|
||||
android:src="@mipmap/icon"/>
|
||||
<ImageButton
|
||||
android:id="@+id/widget_compose"
|
||||
android:layout_width="56dip"
|
||||
android:layout_height="56dip"
|
||||
android:layout_marginRight="5dip"
|
||||
android:layout_marginTop="3dip"
|
||||
android:layout_alignParentTop="true"
|
||||
android:layout_alignParentRight="true"
|
||||
android:src="@drawable/ic_menu_compose"/>
|
||||
<TextView
|
||||
android:id="@+id/widget_title"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_toRightOf="@id/widget_logo"
|
||||
android:layout_marginTop="10dip"
|
||||
android:textSize="18sp"
|
||||
android:textColor="#F000"
|
||||
android:textStyle="bold"
|
||||
android:text="@string/widget_unread"
|
||||
android:paddingRight="8dip"
|
||||
android:src="@drawable/ic_email_email_widget_holo" />
|
||||
<LinearLayout
|
||||
android:id="@+id/widget_header"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight = "1"
|
||||
android:orientation="vertical">
|
||||
<TextView
|
||||
android:id="@+id/widget_title"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="-2sp"
|
||||
android:text="@string/widget_all_mail"
|
||||
android:textSize="14sp"
|
||||
android:textStyle="bold"
|
||||
android:textColor="@android:color/white"
|
||||
android:shadowColor="@color/widget_label_shadow_color"
|
||||
android:shadowRadius="3"
|
||||
android:freezesText="true" />
|
||||
<TextView
|
||||
android:id="@+id/widget_tap"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="-2sp"
|
||||
android:singleLine="true"
|
||||
android:text="@string/widget_other_views"
|
||||
android:textSize="14sp"
|
||||
android:textColor="@color/widget_account_color" />
|
||||
</LinearLayout>
|
||||
<TextView
|
||||
android:id="@+id/widget_count"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="-16sp"
|
||||
android:paddingRight="8dip"
|
||||
android:textSize="48sp"
|
||||
android:textColor="@color/widget_unread_count_color"
|
||||
android:freezesText="true" />
|
||||
</RelativeLayout>
|
||||
<ImageView
|
||||
android:id="@+id/widget_compose"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingTop="2dip"
|
||||
android:src="@drawable/btn_ic_new_email_email_widget_holo_dark" />
|
||||
</LinearLayout>
|
||||
<ImageView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@drawable/list_div_top_btm_email_widget_holo" />
|
||||
<ListView
|
||||
android:id="@+id/message_list"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="fill_parent"
|
||||
android:layout_below="@id/widget_header"
|
||||
android:cacheColorHint="#00000000"
|
||||
/>
|
||||
</RelativeLayout>
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:layout_marginLeft="5dip"
|
||||
android:layout_marginRight="5dip"
|
||||
android:paddingTop="6dip"
|
||||
android:clipToPadding="false"
|
||||
android:fadingEdge="none"
|
||||
android:divider="@drawable/list_div_email_widget_holo"
|
||||
android:cacheColorHint="#00000000" />
|
||||
<ImageView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@drawable/list_div_top_btm_email_widget_holo" />
|
||||
</LinearLayout>
|
||||
|
|
|
@ -14,43 +14,46 @@
|
|||
limitations under the License.
|
||||
-->
|
||||
|
||||
<RelativeLayout
|
||||
<LinearLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:id="@+id/widget_message"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical">
|
||||
<TextView
|
||||
android:id="@+id/widget_date"
|
||||
android:layout_width="64dip"
|
||||
android:layout_height="64sp"
|
||||
android:paddingLeft="16dip"
|
||||
android:paddingRight="8dip"
|
||||
android:orientation="vertical"
|
||||
android:background="@drawable/widget_conversation_selector"
|
||||
>
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentRight="true"
|
||||
android:textColor="#F000"
|
||||
android:textSize="14sp"
|
||||
android:paddingLeft="10dip"
|
||||
android:drawablePadding="4dip"
|
||||
/>
|
||||
<TextView
|
||||
android:id="@+id/widget_from"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentLeft="true"
|
||||
android:layout_toLeftOf="@id/widget_date"
|
||||
android:textColor="#F000"
|
||||
android:ellipsize="end"
|
||||
android:singleLine="true"
|
||||
android:textSize="16sp"
|
||||
android:paddingLeft="10dip"
|
||||
android:drawablePadding="4dip"
|
||||
/>
|
||||
<TextView
|
||||
android:id="@+id/widget_subject"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_below="@id/widget_from"
|
||||
android:minLines="2"
|
||||
android:textSize="14sp"
|
||||
android:textColor="#F000"
|
||||
android:paddingLeft="10dip"
|
||||
/>
|
||||
</RelativeLayout>
|
||||
android:layout_marginTop="8sp"
|
||||
android:orientation="horizontal"
|
||||
>
|
||||
<TextView
|
||||
android:id="@+id/widget_from"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:paddingRight="16dip"
|
||||
android:singleLine="true" />
|
||||
<!-- Use negative margins to align attachment icon with text -->
|
||||
<ImageView
|
||||
android:id="@+id/widget_attachment"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="-10sp"
|
||||
android:layout_marginRight="-4dip"
|
||||
android:src="@drawable/ic_attachment_holo_light" />
|
||||
<TextView
|
||||
android:id="@+id/widget_date"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content" />
|
||||
</LinearLayout>
|
||||
<TextView
|
||||
android:id="@+id/widget_subject"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_marginTop="-4sp"
|
||||
android:maxLines="2"/>
|
||||
</LinearLayout>
|
|
@ -26,4 +26,8 @@
|
|||
<dimen name="mailbox_list_width">304dip</dimen>
|
||||
<!-- width of the message list, on the message list + message view mode. -->
|
||||
<dimen name="message_list_width">466dip</dimen>
|
||||
|
||||
<dimen name="widget_senders_font_size">14sp</dimen>
|
||||
<dimen name="widget_subject_font_size">14sp</dimen>
|
||||
<dimen name="widget_date_font_size">14sp</dimen>
|
||||
</resources>
|
||||
|
|
|
@ -29,4 +29,8 @@
|
|||
(i.e. on portrait, it's the "expanded" message list.)
|
||||
-->
|
||||
<dimen name="message_list_width">440dip</dimen>
|
||||
|
||||
<dimen name="widget_senders_font_size">14sp</dimen>
|
||||
<dimen name="widget_subject_font_size">14sp</dimen>
|
||||
<dimen name="widget_date_font_size">14sp</dimen>
|
||||
</resources>
|
||||
|
|
|
@ -22,4 +22,11 @@
|
|||
<color name="account_setup_divider_color">#b6d650</color>
|
||||
|
||||
<color name="message_view_fogged_glass_color">#00000000</color>
|
||||
|
||||
<!-- Widget colors -->
|
||||
<color name="widget_label_shadow_color">#0d0d0d</color>
|
||||
<color name="widget_account_color">#666666</color>
|
||||
<color name="widget_unread_count_color">#4d4d4d</color>
|
||||
<color name="widget_default_text_color">#000000</color>
|
||||
<color name="widget_light_text_color">#666666</color>
|
||||
</resources>
|
||||
|
|
|
@ -37,4 +37,11 @@
|
|||
<color name="combined_view_account_color_3">#ff009b8b</color>
|
||||
<color name="combined_view_account_color_4">#fff4fd04</color>
|
||||
<color name="combined_view_account_color_5">#ffe65020</color>
|
||||
|
||||
<!-- Widget colors -->
|
||||
<color name="widget_label_shadow_color">#0d0d0d</color>
|
||||
<color name="widget_account_color">#666666</color>
|
||||
<color name="widget_unread_count_color">#4d4d4d</color>
|
||||
<color name="widget_default_text_color">#000000</color>
|
||||
<color name="widget_light_text_color">#666666</color>
|
||||
</resources>
|
||||
|
|
|
@ -37,4 +37,8 @@
|
|||
<dimen name="message_list_item_color_tip_right_margin_on_wide">65dip</dimen>
|
||||
|
||||
<dimen name="error_message_height">48dip</dimen>
|
||||
|
||||
<dimen name="widget_senders_font_size">14sp</dimen>
|
||||
<dimen name="widget_subject_font_size">14sp</dimen>
|
||||
<dimen name="widget_date_font_size">14sp</dimen>
|
||||
</resources>
|
||||
|
|
|
@ -997,7 +997,7 @@ save attachment.</string>
|
|||
|
||||
<!-- Widget -->
|
||||
<!-- Instruction for how to move to different widget views [CHAR LIMIT=50] -->
|
||||
<string name="widget_other_views">Tap email icon for other views</string>
|
||||
<string name="widget_other_views">Tap icon to configure</string>
|
||||
<!-- Header for the "All Mail" widget view (showing all of the user's mail) [CHAR LIMIT=20] -->
|
||||
<string name="widget_all_mail">All Mail</string>
|
||||
<!-- Header for the "Unread" widget view (showing all unread mail) [CHAR LIMIT=20] -->
|
||||
|
|
|
@ -15,9 +15,9 @@
|
|||
-->
|
||||
|
||||
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:minWidth="220dp"
|
||||
android:minHeight="220dp"
|
||||
android:minWidth="258dip"
|
||||
android:minHeight="258dip"
|
||||
android:updatePeriodMillis="0"
|
||||
android:initialLayout="@layout/widget"
|
||||
android:previewImage="@drawable/email_widget_preview"
|
||||
android:initialLayout="@layout/widget"
|
||||
/>
|
||||
|
|
|
@ -36,20 +36,22 @@ import android.content.ContentUris;
|
|||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.Loader;
|
||||
import android.content.res.Resources;
|
||||
import android.database.Cursor;
|
||||
import android.graphics.Typeface;
|
||||
import android.graphics.Paint.Align;
|
||||
import android.net.Uri;
|
||||
import android.net.Uri.Builder;
|
||||
import android.os.Bundle;
|
||||
import android.text.Spannable;
|
||||
import android.text.SpannableString;
|
||||
import android.text.TextPaint;
|
||||
import android.text.SpannableStringBuilder;
|
||||
import android.text.TextUtils;
|
||||
import android.text.TextUtils.TruncateAt;
|
||||
import android.text.format.DateUtils;
|
||||
import android.text.style.AbsoluteSizeSpan;
|
||||
import android.text.style.ForegroundColorSpan;
|
||||
import android.text.style.StyleSpan;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
import android.widget.RemoteViews;
|
||||
import android.widget.RemoteViewsService;
|
||||
|
||||
|
@ -98,7 +100,14 @@ public class WidgetProvider extends AppWidgetProvider {
|
|||
private static AppWidgetManager sWidgetManager;
|
||||
private static Context sContext;
|
||||
private static ContentResolver sResolver;
|
||||
private static TextPaint sDatePaint = new TextPaint();
|
||||
|
||||
private static int sSenderFontSize;
|
||||
private static int sSubjectFontSize;
|
||||
private static int sDateFontSize;
|
||||
private static int sDefaultTextColor;
|
||||
private static int sLightTextColor;
|
||||
private static String sSubjectSnippetDivider;
|
||||
private static String sConfigureText;
|
||||
|
||||
/**
|
||||
* Types of views that we're prepared to show in the widget - all mail, unread mail, and starred
|
||||
|
@ -169,12 +178,19 @@ public class WidgetProvider extends AppWidgetProvider {
|
|||
}
|
||||
mWidgetId = _widgetId;
|
||||
mLoader = new WidgetLoader();
|
||||
if (sDatePaint == null) {
|
||||
sDatePaint = new TextPaint();
|
||||
sDatePaint.setTypeface(Typeface.DEFAULT);
|
||||
sDatePaint.setTextSize(14);
|
||||
sDatePaint.setAntiAlias(true);
|
||||
sDatePaint.setTextAlign(Align.RIGHT);
|
||||
if (sSubjectSnippetDivider == null) {
|
||||
// Initialize string, color, dimension resources
|
||||
Resources res = sContext.getResources();
|
||||
sSubjectSnippetDivider =
|
||||
res.getString(R.string.message_list_subject_snippet_divider);
|
||||
sSenderFontSize = res.getDimensionPixelSize(R.dimen.widget_senders_font_size);
|
||||
sSubjectFontSize = res.getDimensionPixelSize(R.dimen.widget_subject_font_size);
|
||||
sDateFontSize = res.getDimensionPixelSize(R.dimen.widget_date_font_size);
|
||||
sDefaultTextColor = res.getColor(R.color.widget_default_text_color);
|
||||
sDefaultTextColor = res.getColor(R.color.widget_default_text_color);
|
||||
sLightTextColor = res.getColor(R.color.widget_light_text_color);
|
||||
sConfigureText = res.getString(R.string.widget_other_views);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -203,8 +219,7 @@ public class WidgetProvider extends AppWidgetProvider {
|
|||
}
|
||||
RemoteViews views =
|
||||
new RemoteViews(sContext.getPackageName(), R.layout.widget);
|
||||
views.setTextViewText(R.id.widget_title,
|
||||
mViewType.getTitle(sContext) + " (" + mCursorCount + ")");
|
||||
setupTitleAndCount(views);
|
||||
sWidgetManager.partiallyUpdateAppWidget(mWidgetId, views);
|
||||
sWidgetManager.notifyAppWidgetViewDataChanged(mWidgetId, R.id.message_list);
|
||||
}
|
||||
|
@ -219,7 +234,7 @@ public class WidgetProvider extends AppWidgetProvider {
|
|||
* @param selection a valid query selection argument
|
||||
*/
|
||||
void startLoadingWithSelection(String selection) {
|
||||
stopLoading();
|
||||
reset();
|
||||
setSelection(selection);
|
||||
startLoading();
|
||||
}
|
||||
|
@ -256,25 +271,6 @@ public class WidgetProvider extends AppWidgetProvider {
|
|||
sWidgetManager.notifyAppWidgetViewDataChanged(mWidgetId, R.id.message_list);
|
||||
}
|
||||
|
||||
private void setStyleSpan(SpannableString str, int typeface) {
|
||||
int length = str.length();
|
||||
str.setSpan(new StyleSpan(typeface), 0, length, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
|
||||
}
|
||||
|
||||
private CharSequence formattedText(String str, int typeface) {
|
||||
if (str == null) {
|
||||
return "";
|
||||
}
|
||||
SpannableString ss = new SpannableString(str);
|
||||
setStyleSpan(ss, typeface);
|
||||
return ss;
|
||||
}
|
||||
|
||||
private CharSequence formattedTextFromCursor(Cursor c, int column, int typeface) {
|
||||
return formattedText(mCursor.getString(column), typeface);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Convenience method for creating an onClickPendingIntent that executes a command via
|
||||
* our command Uri. Used for the "next view" command; appends the widget id to the command
|
||||
|
@ -327,6 +323,16 @@ public class WidgetProvider extends AppWidgetProvider {
|
|||
views.setOnClickFillInIntent(viewId, intent);
|
||||
}
|
||||
|
||||
private void setupTitleAndCount(RemoteViews views) {
|
||||
// Set up the title (view type + count of messages)
|
||||
views.setTextViewText(R.id.widget_title, mViewType.getTitle(sContext));
|
||||
views.setTextViewText(R.id.widget_tap, sConfigureText);
|
||||
String count = "";
|
||||
if (mCursorCount != TOTAL_COUNT_UNKNOWN) {
|
||||
count = Integer.toString(mCursor.getCount());
|
||||
}
|
||||
views.setTextViewText(R.id.widget_count, count);
|
||||
}
|
||||
/**
|
||||
* Update the "header" of the widget (i.e. everything that doesn't include the scrolling
|
||||
* message list)
|
||||
|
@ -341,13 +347,11 @@ public class WidgetProvider extends AppWidgetProvider {
|
|||
|
||||
// Set up the list with an adapter
|
||||
Intent intent = new Intent(sContext, WidgetService.class);
|
||||
intent.setData(Uri.parse(intent.toUri(Intent.URI_INTENT_SCHEME)));
|
||||
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, mWidgetId);
|
||||
intent.setData(Uri.parse(intent.toUri(Intent.URI_INTENT_SCHEME)));
|
||||
views.setRemoteAdapter(R.id.message_list, intent);
|
||||
|
||||
// Set up the title (view type + count of messages)
|
||||
views.setTextViewText(R.id.widget_title,
|
||||
mViewType.getTitle(sContext) + " (" + mCursorCount + ")");
|
||||
setupTitleAndCount(views);
|
||||
|
||||
// Set up "new" button (compose new message) and "next view" button
|
||||
setActivityIntent(views, R.id.widget_compose, MessageCompose.class);
|
||||
|
@ -356,39 +360,107 @@ public class WidgetProvider extends AppWidgetProvider {
|
|||
// Use a bare intent for our template; we need to fill everything in
|
||||
intent = new Intent(sContext, WidgetService.class);
|
||||
PendingIntent pendingIntent =
|
||||
PendingIntent.getService(sContext, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT);
|
||||
PendingIntent.getService(sContext, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
|
||||
views.setPendingIntentTemplate(R.id.message_list, pendingIntent);
|
||||
|
||||
// And finally update the widget
|
||||
sWidgetManager.updateAppWidget(mWidgetId, views);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add size and color styling to text
|
||||
*
|
||||
* @param text the text to style
|
||||
* @param size the font size for this text
|
||||
* @param color the color for this text
|
||||
* @return a CharSequence quitable for use in RemoteViews.setTextViewText()
|
||||
*/
|
||||
private CharSequence addStyle(CharSequence text, int size, int color) {
|
||||
SpannableStringBuilder builder = new SpannableStringBuilder(text);
|
||||
builder.setSpan(
|
||||
new AbsoluteSizeSpan(size), 0, text.length(),
|
||||
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
|
||||
if (color != 0) {
|
||||
builder.setSpan(new ForegroundColorSpan(color), 0, text.length(),
|
||||
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
|
||||
}
|
||||
return builder;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create styled text for our combination subject and snippet
|
||||
*
|
||||
* @param subject the message's subject (or null)
|
||||
* @param snippet the message's snippet (or null)
|
||||
* @param read whether or not the message is read
|
||||
* @return a CharSequence suitable for use in RemoteViews.setTextViewText()
|
||||
*/
|
||||
private CharSequence getStyledSubjectSnippet (String subject, String snippet,
|
||||
boolean read) {
|
||||
SpannableStringBuilder ssb = new SpannableStringBuilder();
|
||||
boolean hasSubject = false;
|
||||
if (!TextUtils.isEmpty(subject)) {
|
||||
SpannableString ss = new SpannableString(subject);
|
||||
ss.setSpan(new StyleSpan(read ? Typeface.NORMAL : Typeface.BOLD), 0, ss.length(),
|
||||
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
|
||||
ss.setSpan(new ForegroundColorSpan(sDefaultTextColor), 0, ss.length(),
|
||||
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
|
||||
ssb.append(ss);
|
||||
hasSubject = true;
|
||||
}
|
||||
if (!TextUtils.isEmpty(snippet)) {
|
||||
if (hasSubject) {
|
||||
ssb.append(sSubjectSnippetDivider);
|
||||
}
|
||||
SpannableString ss = new SpannableString(snippet);
|
||||
ss.setSpan(new ForegroundColorSpan(sLightTextColor), 0, snippet.length(),
|
||||
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
|
||||
ssb.append(ss);
|
||||
}
|
||||
return addStyle(ssb, sSubjectFontSize, 0);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see android.widget.RemoteViewsService.RemoteViewsFactory#getViewAt(int)
|
||||
*/
|
||||
public RemoteViews getViewAt(int position) {
|
||||
// Use the cursor to set up the widget
|
||||
synchronized (mCursorLock) {
|
||||
if (mCursor == null || !mCursor.moveToPosition(position)) {
|
||||
if (mCursor == null || mCursor.isClosed() || !mCursor.moveToPosition(position)) {
|
||||
return getLoadingView();
|
||||
}
|
||||
RemoteViews views =
|
||||
new RemoteViews(sContext.getPackageName(), R.layout.widget_list_item);
|
||||
boolean isUnread = mCursor.getInt(WIDGET_COLUMN_FLAG_READ) != 1;
|
||||
|
||||
// Typeface for from, subject, and date (normal/bold) depends on whether the message
|
||||
// is read/unread
|
||||
int typeface = (mCursor.getInt(WIDGET_COLUMN_FLAG_READ) == 0) ? Typeface.BOLD
|
||||
: Typeface.NORMAL;
|
||||
views.setTextViewText(R.id.widget_from,
|
||||
formattedTextFromCursor(mCursor, WIDGET_COLUMN_DISPLAY_NAME, typeface));
|
||||
views.setTextViewText(R.id.widget_subject,
|
||||
formattedTextFromCursor(mCursor, WIDGET_COLUMN_SUBJECT, typeface));
|
||||
// Add style to sender
|
||||
SpannableStringBuilder from =
|
||||
new SpannableStringBuilder(mCursor.getString(WIDGET_COLUMN_DISPLAY_NAME));
|
||||
from.setSpan(
|
||||
isUnread ? new StyleSpan(Typeface.BOLD) : new StyleSpan(Typeface.NORMAL), 0,
|
||||
from.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
|
||||
CharSequence styledFrom = addStyle(from, sSenderFontSize, sDefaultTextColor);
|
||||
views.setTextViewText(R.id.widget_from, styledFrom);
|
||||
|
||||
long timestamp = mCursor.getLong(WIDGET_COLUMN_TIMESTAMP);
|
||||
// Get a nicely formatted date string (relative to today)
|
||||
String date = DateUtils.getRelativeTimeSpanString(sContext, timestamp).toString();
|
||||
views.setTextViewText(R.id.widget_date, TextUtils.ellipsize(date, sDatePaint, 64,
|
||||
TruncateAt.END));
|
||||
// Add style to date
|
||||
CharSequence styledDate = addStyle(date, sDateFontSize, sDefaultTextColor);
|
||||
views.setTextViewText(R.id.widget_date, styledDate);
|
||||
|
||||
// Add style to subject/snippet
|
||||
String subject = mCursor.getString(WIDGET_COLUMN_SUBJECT);
|
||||
String snippet = mCursor.getString(WIDGET_COLUMN_SNIPPET);
|
||||
CharSequence subjectAndSnippet =
|
||||
getStyledSubjectSnippet(subject, snippet, !isUnread);
|
||||
views.setTextViewText(R.id.widget_subject, subjectAndSnippet);
|
||||
|
||||
if (mCursor.getInt(WIDGET_COLUMN_FLAG_ATTACHMENT) != 0) {
|
||||
views.setViewVisibility(R.id.widget_attachment, View.VISIBLE);
|
||||
} else {
|
||||
views.setViewVisibility(R.id.widget_attachment, View.GONE);
|
||||
}
|
||||
|
||||
// Set button intents for view, reply, and delete
|
||||
String messageId = mCursor.getString(WIDGET_COLUMN_ID);
|
||||
|
@ -433,6 +505,13 @@ public class WidgetProvider extends AppWidgetProvider {
|
|||
public void onDataSetChanged() {
|
||||
}
|
||||
|
||||
private void onDeleted() {
|
||||
if (mLoader != null) {
|
||||
mLoader.stopLoading();
|
||||
}
|
||||
sWidgetMap.remove(mWidgetId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroy() {
|
||||
if (mLoader != null) {
|
||||
|
@ -514,7 +593,7 @@ public class WidgetProvider extends AppWidgetProvider {
|
|||
EmailWidget widget = sWidgetMap.get(widgetId);
|
||||
if (widget != null) {
|
||||
// Stop loading and remove the widget from the map
|
||||
widget.onDestroy();
|
||||
widget.onDeleted();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -545,9 +624,6 @@ public class WidgetProvider extends AppWidgetProvider {
|
|||
@Override
|
||||
public int onStartCommand(Intent intent, int flags, int startId) {
|
||||
Uri data = intent.getData();
|
||||
if (Email.DEBUG) {
|
||||
Log.d(TAG, "Executing: " + data);
|
||||
}
|
||||
if (data == null) return Service.START_NOT_STICKY;
|
||||
List<String> pathSegments = data.getPathSegments();
|
||||
// Our path segments are <command>, <arg1> [, <arg2>]
|
||||
|
@ -583,11 +659,8 @@ public class WidgetProvider extends AppWidgetProvider {
|
|||
}
|
||||
|
||||
private void openMessage(long mailboxId, long messageId) {
|
||||
// TODO Use narrower projection.
|
||||
Mailbox mailbox = Mailbox.restoreMailboxWithId(this, mailboxId);
|
||||
if (mailbox == null) {
|
||||
return;
|
||||
}
|
||||
if (mailbox == null) return;
|
||||
startActivity(Welcome.createOpenMessageIntent(this, mailbox.mAccountKey, mailboxId,
|
||||
messageId));
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue