Add columns to cursor to allow for proper layout

The layout requires different indentation. Although the exact layout may
change, we will likely always need to differentiate between the different
mailbox types.

Change-Id: Ia2ff84b552873f92fa45563b2dc0868c29bec3e3
This commit is contained in:
Todd Kennedy 2011-04-11 16:43:24 -07:00
parent 57dc03acec
commit 2b82c3f0a3
9 changed files with 154 additions and 56 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 633 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 655 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 470 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 450 B

View File

@ -25,15 +25,6 @@
android:layout_height="48dip" android:layout_height="48dip"
android:background="?android:attr/activatedBackgroundIndicator" android:background="?android:attr/activatedBackgroundIndicator"
> >
<ImageView
android:id="@+id/folder_icon"
android:layout_width="32dip"
android:layout_height="32dip"
android:layout_alignParentLeft="true"
android:layout_centerVertical="true"
android:layout_marginRight="8dip"
android:layout_marginLeft="@dimen/mailbox_list_padding_left"
/>
<TextView <TextView
android:id="@+id/message_count" android:id="@+id/message_count"
android:layout_width="wrap_content" android:layout_width="wrap_content"
@ -47,26 +38,51 @@
android:textSize="14dip" android:textSize="14dip"
android:textColor="@color/text_secondary_color" android:textColor="@color/text_secondary_color"
/> />
<TextView <RelativeLayout
android:id="@+id/mailbox_name" android:layout_alignParentLeft="true"
android:layout_centerVertical="true"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_toRightOf="@id/folder_icon" android:layout_marginLeft="@dimen/mailbox_list_padding_left"
android:layout_toLeftOf="@id/message_count" >
android:layout_centerVertical="true" <ImageView
android:ellipsize="end" android:id="@+id/folder_icon"
android:singleLine="true" android:layout_width="32dip"
android:textSize="18dip" android:layout_height="32dip"
android:textColor="@color/text_primary_color" android:layout_centerVertical="true"
/> android:layout_marginRight="8dip"
<!-- Color chips are shown only for account rows on combined view. --> />
<View <ImageView
android:id="@+id/color_chip" android:id="@+id/folder_expanded_icon"
android:layout_width="32dip" android:layout_width="32dip"
android:layout_height="8dip" android:layout_height="32dip"
android:layout_marginLeft="16dip" android:layout_toRightOf="@id/folder_icon"
android:layout_alignParentTop="true" android:layout_centerVertical="true"
android:layout_alignParentLeft="true" android:layout_marginRight="8dip"
android:visibility="gone" android:layout_marginLeft="8dip"
/> android:visibility="gone"
/>
<TextView
android:id="@+id/mailbox_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toRightOf="@id/folder_expanded_icon"
android:layout_toLeftOf="@id/message_count"
android:layout_centerVertical="true"
android:ellipsize="end"
android:singleLine="true"
android:textSize="18dip"
android:textColor="@color/text_primary_color"
/>
<!-- Color chips are shown only for account rows on combined view. -->
<View
android:id="@+id/color_chip"
android:layout_width="32dip"
android:layout_height="8dip"
android:layout_marginLeft="16dip"
android:layout_alignParentTop="true"
android:layout_alignParentLeft="true"
android:visibility="gone"
/>
</RelativeLayout>
</com.android.email.activity.MailboxListItem> </com.android.email.activity.MailboxListItem>

View File

@ -37,6 +37,7 @@ public class FolderProperties {
private final TypedArray mSpecialMailboxDrawable; private final TypedArray mSpecialMailboxDrawable;
private final Drawable mSummaryStarredMailboxDrawable; private final Drawable mSummaryStarredMailboxDrawable;
private final Drawable mSummaryCombinedInboxDrawable; private final Drawable mSummaryCombinedInboxDrawable;
private final Drawable mMailboxCollapsedDrawable;
private FolderProperties(Context context) { private FolderProperties(Context context) {
mContext = context.getApplicationContext(); mContext = context.getApplicationContext();
@ -53,6 +54,8 @@ public class FolderProperties {
context.getResources().getDrawable(R.drawable.ic_folder_star_holo_light); context.getResources().getDrawable(R.drawable.ic_folder_star_holo_light);
mSummaryCombinedInboxDrawable = mSummaryCombinedInboxDrawable =
context.getResources().getDrawable(R.drawable.ic_list_combined_inbox); context.getResources().getDrawable(R.drawable.ic_list_combined_inbox);
mMailboxCollapsedDrawable =
context.getResources().getDrawable(R.drawable.ic_mailbox_collapsed_holo_light);
} }
public static synchronized FolderProperties getInstance(Context context) { public static synchronized FolderProperties getInstance(Context context) {
@ -69,7 +72,7 @@ public class FolderProperties {
// For backward compatibility. // For backward compatibility.
public Drawable getSummaryMailboxIconIds(long id) { public Drawable getSummaryMailboxIconIds(long id) {
return getIcon(-1, id); return getIcon(-1, id, 0);
} }
/** /**
@ -102,7 +105,7 @@ public class FolderProperties {
/** /**
* Lookup icons of special mailboxes * Lookup icons of special mailboxes
*/ */
public Drawable getIcon(int type, long mailboxId) { public Drawable getIcon(int type, long mailboxId, int mailboxFlags) {
if (mailboxId == Mailbox.QUERY_ALL_INBOXES) { if (mailboxId == Mailbox.QUERY_ALL_INBOXES) {
return mSummaryCombinedInboxDrawable; return mSummaryCombinedInboxDrawable;
} else if (mailboxId == Mailbox.QUERY_ALL_FAVORITES) { } else if (mailboxId == Mailbox.QUERY_ALL_FAVORITES) {
@ -118,6 +121,10 @@ public class FolderProperties {
return mContext.getResources().getDrawable(resId); return mContext.getResources().getDrawable(resId);
} }
} }
if ((mailboxFlags & Mailbox.FLAG_HAS_CHILDREN) != 0 &&
(mailboxFlags & Mailbox.FLAG_CHILDREN_VISIBLE) != 0) {
return mMailboxCollapsedDrawable;
}
return null; // No icon return null; // No icon
} }
} }

View File

@ -43,7 +43,18 @@ import android.widget.ImageView;
import android.widget.TextView; import android.widget.TextView;
/** /**
* Cursor adapter for a fragment mailbox list. * Mailbox cursor adapter for the mailbox list fragment.
*
* A mailbox cursor may contain one of several different types of data. Currently, this
* adapter supports the following views:
* 1. The standard inbox, mailbox view
* 2. The combined mailbox view
* 3. Nested folder navigation
*
* TODO At a minimum, we should break out the loaders. They have no relation to the view code
* and only serve to confuse the user.
* TODO Determine if we actually need a separate adapter / view / loader for nested folder
* navigation. It's a little convoluted at the moment, but, still manageable.
*/ */
/*package*/ class MailboxFragmentAdapter extends MailboxesAdapter { /*package*/ class MailboxFragmentAdapter extends MailboxesAdapter {
private static final String MAILBOX_SELECTION = MailboxColumns.ACCOUNT_KEY + "=?" + private static final String MAILBOX_SELECTION = MailboxColumns.ACCOUNT_KEY + "=?" +
@ -57,6 +68,7 @@ import android.widget.TextView;
final boolean isAccount = isAccountRow(cursor); final boolean isAccount = isAccountRow(cursor);
final int type = cursor.getInt(COLUMN_TYPE); final int type = cursor.getInt(COLUMN_TYPE);
final long id = cursor.getLong(COLUMN_ID); final long id = cursor.getLong(COLUMN_ID);
final int flags = cursor.getInt(COLUMN_FLAGS);
MailboxListItem listItem = (MailboxListItem)view; MailboxListItem listItem = (MailboxListItem)view;
listItem.mMailboxType = type; listItem.mMailboxType = type;
@ -86,6 +98,37 @@ import android.widget.TextView;
} }
final TextView countView = (TextView) view.findViewById(R.id.message_count); final TextView countView = (TextView) view.findViewById(R.id.message_count);
final ImageView mailboxExpandedIcon =
(ImageView) view.findViewById(R.id.folder_expanded_icon);
final ImageView folderIcon = (ImageView) view.findViewById(R.id.folder_icon);
switch (cursor.getInt(COLUMN_ROW_TYPE)) {
case ROW_TYPE_ALLMAILBOX:
mailboxExpandedIcon.setVisibility(View.VISIBLE);
mailboxExpandedIcon.setImageResource(R.drawable.ic_mailbox_expanded_holo_light);
folderIcon.setVisibility(View.INVISIBLE);
break;
case ROW_TYPE_SUBMAILBOX:
if ((flags & Mailbox.FLAG_HAS_CHILDREN) != 0 &&
(flags & Mailbox.FLAG_CHILDREN_VISIBLE) != 0) {
mailboxExpandedIcon.setVisibility(View.VISIBLE);
mailboxExpandedIcon.setImageResource(
R.drawable.ic_mailbox_collapsed_holo_light);
} else {
mailboxExpandedIcon.setVisibility(View.INVISIBLE);
mailboxExpandedIcon.setImageDrawable(null);
}
folderIcon.setVisibility(View.INVISIBLE);
break;
case ROW_TYPE_CURMAILBOX:
folderIcon.setVisibility(View.GONE);
break;
default:
mailboxExpandedIcon.setVisibility(View.GONE);
mailboxExpandedIcon.setImageDrawable(null);
folderIcon.setVisibility(View.VISIBLE);
break;
}
// If the unread count is zero, not to show countView. // If the unread count is zero, not to show countView.
if (count > 0) { if (count > 0) {
countView.setVisibility(View.VISIBLE); countView.setVisibility(View.VISIBLE);
@ -95,8 +138,8 @@ import android.widget.TextView;
} }
// Set folder icon // Set folder icon
((ImageView) view.findViewById(R.id.folder_icon)).setImageDrawable( folderIcon.setImageDrawable(
FolderProperties.getInstance(context).getIcon(type, id)); FolderProperties.getInstance(context).getIcon(type, id, flags));
final View chipView = view.findViewById(R.id.color_chip); final View chipView = view.findViewById(R.id.color_chip);
if (isAccount) { if (isAccount) {
@ -139,7 +182,7 @@ import android.widget.TextView;
* Adds a new row into the given cursor. * Adds a new row into the given cursor.
*/ */
private static void addMailboxRow(MatrixCursor cursor, long mailboxId, String displayName, private static void addMailboxRow(MatrixCursor cursor, long mailboxId, String displayName,
int mailboxType, int unreadCount, int messageCount) { int mailboxType, int unreadCount, int messageCount, int rowType, int flags) {
long listId = mailboxId; long listId = mailboxId;
if (mailboxId < 0) { if (mailboxId < 0) {
listId = Long.MAX_VALUE + mailboxId; // IDs for the list view must be positive listId = Long.MAX_VALUE + mailboxId; // IDs for the list view must be positive
@ -151,7 +194,8 @@ import android.widget.TextView;
row.add(mailboxType); row.add(mailboxType);
row.add(unreadCount); row.add(unreadCount);
row.add(messageCount); row.add(messageCount);
row.add(ROW_TYPE_MAILBOX); row.add(rowType);
row.add(flags);
} }
private static void addSummaryMailboxRow(MatrixCursor cursor, long id, int mailboxType, private static void addSummaryMailboxRow(MatrixCursor cursor, long id, int mailboxType,
@ -160,7 +204,7 @@ import android.widget.TextView;
throw new IllegalArgumentException(); // Must be QUERY_ALL_*, which are all negative throw new IllegalArgumentException(); // Must be QUERY_ALL_*, which are all negative
} }
if (showAlways || (count > 0)) { if (showAlways || (count > 0)) {
addMailboxRow(cursor, id, "", mailboxType, count, count); addMailboxRow(cursor, id, "", mailboxType, count, count, ROW_TYPE_MAILBOX, 0);
} }
} }
@ -185,7 +229,9 @@ import android.widget.TextView;
MailboxFragmentLoader(Context context, long accountId, long parentKey) { MailboxFragmentLoader(Context context, long accountId, long parentKey) {
super(context, EmailContent.Mailbox.CONTENT_URI, super(context, EmailContent.Mailbox.CONTENT_URI,
MailboxesAdapter.PROJECTION, MAILBOX_SELECTION_WITH_PARENT, (parentKey > 0) ? MailboxesAdapter.SUBMAILBOX_PROJECTION
: MailboxesAdapter.PROJECTION,
MAILBOX_SELECTION_WITH_PARENT,
new String[] { Long.toString(accountId), Long.toString(parentKey) }, new String[] { Long.toString(accountId), Long.toString(parentKey) },
MAILBOX_ORDER_BY); MAILBOX_ORDER_BY);
mContext = context; mContext = context;
@ -215,12 +261,13 @@ import android.widget.TextView;
if (superParentKey != null) { if (superParentKey != null) {
final Cursor parentCursor = getContext().getContentResolver().query( final Cursor parentCursor = getContext().getContentResolver().query(
Mailbox.CONTENT_URI, getProjection(), MAILBOX_SELECTION, Mailbox.CONTENT_URI, CURMAILBOX_PROJECTION, MAILBOX_SELECTION,
new String[] { Long.toString(mAccountId), Long.toString(mParentKey) }, new String[] { Long.toString(mAccountId), Long.toString(mParentKey) },
null); null);
final MatrixCursor extraCursor = new MatrixCursor(getProjection()); final MatrixCursor extraCursor = new MatrixCursor(getProjection());
String label = mContext.getResources().getString(R.string.mailbox_name_go_back); String label = mContext.getResources().getString(R.string.mailbox_name_go_back);
addMailboxRow(extraCursor, superParentKey, label, Mailbox.TYPE_MAIL, 0, 0); addMailboxRow(extraCursor, superParentKey, label, Mailbox.TYPE_MAIL, 0, 0,
ROW_TYPE_ALLMAILBOX, 0);
return Utility.CloseTraceCursorWrapper.get(new MergeCursor( return Utility.CloseTraceCursorWrapper.get(new MergeCursor(
new Cursor[] { extraCursor, parentCursor, childMailboxCursor })); new Cursor[] { extraCursor, parentCursor, childMailboxCursor }));
} }

View File

@ -39,9 +39,9 @@ import android.widget.CursorAdapter;
/** /**
* Return value from {@link #getCountType}. * Return value from {@link #getCountType}.
*/ */
public static final int COUNT_TYPE_UNREAD = 0; static final int COUNT_TYPE_UNREAD = 0;
public static final int COUNT_TYPE_TOTAL = 1; static final int COUNT_TYPE_TOTAL = 1;
public static final int COUNT_TYPE_NO_COUNT = 2; static final int COUNT_TYPE_NO_COUNT = 2;
/** /**
* Callback interface used to report clicks other than the basic list item click or long press. * Callback interface used to report clicks other than the basic list item click or long press.
@ -52,14 +52,24 @@ import android.widget.CursorAdapter;
} }
/** /**
* Row type, used in the "row_type" in {@link #PROJECTION}. * The type of the row to present to the user. There are 4 defined rows that each
* {@link #ROW_TYPE_MAILBOX} for regular mailboxes and combined mailboxes. * have a slightly different look. These are typically used in the constant column
* {@link #ROW_TYPE_ACCOUNT} for account row in the combined view. * <code>row_type</code> specified in {@link #PROJECTION} and {@link #SUBMAILBOX_PROJECTION}.
*/ */
/** Both regular and combined mailboxes */
static final int ROW_TYPE_MAILBOX = 0; static final int ROW_TYPE_MAILBOX = 0;
/** Account "mailboxes" in the combined view */
static final int ROW_TYPE_ACCOUNT = 1; static final int ROW_TYPE_ACCOUNT = 1;
// STOPSHIP Need to determine if these types are sufficient for nested folders
// The following types are used when drilling into a mailbox
/** The current mailbox */
static final int ROW_TYPE_CURMAILBOX = 2;
/** Sub mailboxes */
static final int ROW_TYPE_SUBMAILBOX = 3;
/** The "All Folders" mailbox */
static final int ROW_TYPE_ALLMAILBOX = 4;
/* /**
* Note here we have two ID columns. The first one is for ListView, which doesn't like ID * Note here we have two ID columns. The first one is for ListView, which doesn't like ID
* values to be negative. The second one is the actual mailbox ID, which we use in the rest * values to be negative. The second one is the actual mailbox ID, which we use in the rest
* of code. * of code.
@ -71,7 +81,24 @@ import android.widget.CursorAdapter;
/*package*/ static final String[] PROJECTION = new String[] { MailboxColumns.ID, /*package*/ static final String[] PROJECTION = new String[] { MailboxColumns.ID,
MailboxColumns.ID + " AS org_mailbox_id", MailboxColumns.ID + " AS org_mailbox_id",
MailboxColumns.DISPLAY_NAME, MailboxColumns.TYPE, MailboxColumns.UNREAD_COUNT, MailboxColumns.DISPLAY_NAME, MailboxColumns.TYPE, MailboxColumns.UNREAD_COUNT,
MailboxColumns.MESSAGE_COUNT, ROW_TYPE_MAILBOX + " AS row_type" }; MailboxColumns.MESSAGE_COUNT, ROW_TYPE_MAILBOX + " AS row_type",
MailboxColumns.FLAGS };
// STOPSHIP May need to adjust sub-folder projection depending upon final UX
/**
* Projection used to retrieve immediate children for a mailbox. The columns need to
* be identical to those in {@link #PROJECTION}. We are only changing the constant
* column <code>row_type</code>.
*/
/*package*/ static final String[] SUBMAILBOX_PROJECTION = new String[] { MailboxColumns.ID,
MailboxColumns.ID + " AS org_mailbox_id",
MailboxColumns.DISPLAY_NAME, MailboxColumns.TYPE, MailboxColumns.UNREAD_COUNT,
MailboxColumns.MESSAGE_COUNT, ROW_TYPE_SUBMAILBOX + " AS row_type",
MailboxColumns.FLAGS };
/*package*/ static final String[] CURMAILBOX_PROJECTION = new String[] { MailboxColumns.ID,
MailboxColumns.ID + " AS org_mailbox_id",
MailboxColumns.DISPLAY_NAME, MailboxColumns.TYPE, MailboxColumns.UNREAD_COUNT,
MailboxColumns.MESSAGE_COUNT, ROW_TYPE_CURMAILBOX + " AS row_type",
MailboxColumns.FLAGS };
// Column 0 is only for ListView; we don't use it in our code. // Column 0 is only for ListView; we don't use it in our code.
static final int COLUMN_ID = 1; static final int COLUMN_ID = 1;
@ -80,6 +107,7 @@ import android.widget.CursorAdapter;
static final int COLUMN_UNREAD_COUNT = 4; static final int COLUMN_UNREAD_COUNT = 4;
static final int COLUMN_MESSAGE_COUNT = 5; static final int COLUMN_MESSAGE_COUNT = 5;
static final int COLUMN_ROW_TYPE = 6; static final int COLUMN_ROW_TYPE = 6;
static final int COLUMN_FLAGS = 7;
/** All mailboxes for the account */ /** All mailboxes for the account */
static final String ALL_MAILBOX_SELECTION = MailboxColumns.ACCOUNT_KEY + "=?" + static final String ALL_MAILBOX_SELECTION = MailboxColumns.ACCOUNT_KEY + "=?" +

View File

@ -106,14 +106,14 @@ public class UtilityUnitTests extends AndroidTestCase {
FolderProperties fp = FolderProperties.getInstance(mContext); FolderProperties fp = FolderProperties.getInstance(mContext);
// Make sure they're available // Make sure they're available
Drawable inbox = fp.getIcon(Mailbox.TYPE_INBOX, -1); Drawable inbox = fp.getIcon(Mailbox.TYPE_INBOX, -1, 0);
Drawable mail = fp.getIcon(Mailbox.TYPE_MAIL, -1); Drawable mail = fp.getIcon(Mailbox.TYPE_MAIL, -1, 0);
Drawable parent = fp.getIcon(Mailbox.TYPE_PARENT, -1); Drawable parent = fp.getIcon(Mailbox.TYPE_PARENT, -1, 0);
Drawable drafts = fp.getIcon(Mailbox.TYPE_DRAFTS, -1); Drawable drafts = fp.getIcon(Mailbox.TYPE_DRAFTS, -1, 0);
Drawable outbox = fp.getIcon(Mailbox.TYPE_OUTBOX, -1); Drawable outbox = fp.getIcon(Mailbox.TYPE_OUTBOX, -1, 0);
Drawable sent = fp.getIcon(Mailbox.TYPE_SENT, -1); Drawable sent = fp.getIcon(Mailbox.TYPE_SENT, -1, 0);
Drawable trash = fp.getIcon(Mailbox.TYPE_TRASH, -1); Drawable trash = fp.getIcon(Mailbox.TYPE_TRASH, -1, 0);
Drawable junk = fp.getIcon(Mailbox.TYPE_JUNK, -1); Drawable junk = fp.getIcon(Mailbox.TYPE_JUNK, -1, 0);
// Make sure they're unique // Make sure they're unique
Set<Drawable> set = new HashSet<Drawable>(); Set<Drawable> set = new HashSet<Drawable>();