diff options
69 files changed, 992 insertions, 646 deletions
diff --git a/res/drawable-hdpi/ic_drawer_drafts_24dp.png b/res/drawable-hdpi/ic_drawer_drafts_24dp.png Binary files differindex 949072ca6..0b7bc9792 100644 --- a/res/drawable-hdpi/ic_drawer_drafts_24dp.png +++ b/res/drawable-hdpi/ic_drawer_drafts_24dp.png diff --git a/res/drawable-hdpi/ic_drawer_folder_24dp.png b/res/drawable-hdpi/ic_drawer_folder_24dp.png Binary files differindex 2d3db4758..69f4a18cc 100644 --- a/res/drawable-hdpi/ic_drawer_folder_24dp.png +++ b/res/drawable-hdpi/ic_drawer_folder_24dp.png diff --git a/res/drawable-hdpi/ic_drawer_help_24dp.png b/res/drawable-hdpi/ic_drawer_help_24dp.png Binary files differindex c7a1081cf..324498c0d 100644 --- a/res/drawable-hdpi/ic_drawer_help_24dp.png +++ b/res/drawable-hdpi/ic_drawer_help_24dp.png diff --git a/res/drawable-hdpi/ic_drawer_inbox_24dp.png b/res/drawable-hdpi/ic_drawer_inbox_24dp.png Binary files differindex aa987f81e..54c04eaf7 100644 --- a/res/drawable-hdpi/ic_drawer_inbox_24dp.png +++ b/res/drawable-hdpi/ic_drawer_inbox_24dp.png diff --git a/res/drawable-hdpi/ic_drawer_outbox_24dp.png b/res/drawable-hdpi/ic_drawer_outbox_24dp.png Binary files differindex dd6ffe384..3119d9a9d 100644 --- a/res/drawable-hdpi/ic_drawer_outbox_24dp.png +++ b/res/drawable-hdpi/ic_drawer_outbox_24dp.png diff --git a/res/drawable-hdpi/ic_drawer_sent_24dp.png b/res/drawable-hdpi/ic_drawer_sent_24dp.png Binary files differindex 0cbdfaba9..b771392ed 100644 --- a/res/drawable-hdpi/ic_drawer_sent_24dp.png +++ b/res/drawable-hdpi/ic_drawer_sent_24dp.png diff --git a/res/drawable-hdpi/ic_drawer_settings_24dp.png b/res/drawable-hdpi/ic_drawer_settings_24dp.png Binary files differindex 30ce2577a..3e4d23436 100644 --- a/res/drawable-hdpi/ic_drawer_settings_24dp.png +++ b/res/drawable-hdpi/ic_drawer_settings_24dp.png diff --git a/res/drawable-hdpi/ic_drawer_starred_24dp.png b/res/drawable-hdpi/ic_drawer_starred_24dp.png Binary files differindex 41e657c21..de7502f9d 100644 --- a/res/drawable-hdpi/ic_drawer_starred_24dp.png +++ b/res/drawable-hdpi/ic_drawer_starred_24dp.png diff --git a/res/drawable-hdpi/ic_drawer_trash_24dp.png b/res/drawable-hdpi/ic_drawer_trash_24dp.png Binary files differindex a9451feb8..b72a9f3c6 100644 --- a/res/drawable-hdpi/ic_drawer_trash_24dp.png +++ b/res/drawable-hdpi/ic_drawer_trash_24dp.png diff --git a/res/drawable-hdpi/ic_drawer_unread_24dp.png b/res/drawable-hdpi/ic_drawer_unread_24dp.png Binary files differindex ed21b08c3..56c0a8c94 100644 --- a/res/drawable-hdpi/ic_drawer_unread_24dp.png +++ b/res/drawable-hdpi/ic_drawer_unread_24dp.png diff --git a/res/drawable-hdpi/ic_folder_parent_24dp.png b/res/drawable-hdpi/ic_folder_parent_24dp.png Binary files differindex 68a6f4abf..5b709603a 100644 --- a/res/drawable-hdpi/ic_folder_parent_24dp.png +++ b/res/drawable-hdpi/ic_folder_parent_24dp.png diff --git a/res/drawable-mdpi/ic_drawer_drafts_24dp.png b/res/drawable-mdpi/ic_drawer_drafts_24dp.png Binary files differindex d899d1767..e53cf4a42 100644 --- a/res/drawable-mdpi/ic_drawer_drafts_24dp.png +++ b/res/drawable-mdpi/ic_drawer_drafts_24dp.png diff --git a/res/drawable-mdpi/ic_drawer_folder_24dp.png b/res/drawable-mdpi/ic_drawer_folder_24dp.png Binary files differindex c079acfee..1028bfaf3 100644 --- a/res/drawable-mdpi/ic_drawer_folder_24dp.png +++ b/res/drawable-mdpi/ic_drawer_folder_24dp.png diff --git a/res/drawable-mdpi/ic_drawer_help_24dp.png b/res/drawable-mdpi/ic_drawer_help_24dp.png Binary files differindex bf6212fca..1efd1b54c 100644 --- a/res/drawable-mdpi/ic_drawer_help_24dp.png +++ b/res/drawable-mdpi/ic_drawer_help_24dp.png diff --git a/res/drawable-mdpi/ic_drawer_inbox_24dp.png b/res/drawable-mdpi/ic_drawer_inbox_24dp.png Binary files differindex 665c994ed..6034b8aa9 100644 --- a/res/drawable-mdpi/ic_drawer_inbox_24dp.png +++ b/res/drawable-mdpi/ic_drawer_inbox_24dp.png diff --git a/res/drawable-mdpi/ic_drawer_outbox_24dp.png b/res/drawable-mdpi/ic_drawer_outbox_24dp.png Binary files differindex b5589d38f..f20466c9a 100644 --- a/res/drawable-mdpi/ic_drawer_outbox_24dp.png +++ b/res/drawable-mdpi/ic_drawer_outbox_24dp.png diff --git a/res/drawable-mdpi/ic_drawer_sent_24dp.png b/res/drawable-mdpi/ic_drawer_sent_24dp.png Binary files differindex 14a6dbd1b..6fef4883d 100644 --- a/res/drawable-mdpi/ic_drawer_sent_24dp.png +++ b/res/drawable-mdpi/ic_drawer_sent_24dp.png diff --git a/res/drawable-mdpi/ic_drawer_settings_24dp.png b/res/drawable-mdpi/ic_drawer_settings_24dp.png Binary files differindex 0ec76c722..d2963c26c 100644 --- a/res/drawable-mdpi/ic_drawer_settings_24dp.png +++ b/res/drawable-mdpi/ic_drawer_settings_24dp.png diff --git a/res/drawable-mdpi/ic_drawer_starred_24dp.png b/res/drawable-mdpi/ic_drawer_starred_24dp.png Binary files differindex 39c03cdfa..89b79c49b 100644 --- a/res/drawable-mdpi/ic_drawer_starred_24dp.png +++ b/res/drawable-mdpi/ic_drawer_starred_24dp.png diff --git a/res/drawable-mdpi/ic_drawer_trash_24dp.png b/res/drawable-mdpi/ic_drawer_trash_24dp.png Binary files differindex c1583bdda..e757fdb07 100644 --- a/res/drawable-mdpi/ic_drawer_trash_24dp.png +++ b/res/drawable-mdpi/ic_drawer_trash_24dp.png diff --git a/res/drawable-mdpi/ic_drawer_unread_24dp.png b/res/drawable-mdpi/ic_drawer_unread_24dp.png Binary files differindex 75e11cd7b..b971cd9fd 100644 --- a/res/drawable-mdpi/ic_drawer_unread_24dp.png +++ b/res/drawable-mdpi/ic_drawer_unread_24dp.png diff --git a/res/drawable-mdpi/ic_folder_parent_24dp.png b/res/drawable-mdpi/ic_folder_parent_24dp.png Binary files differindex 99d50760f..87bd54783 100644 --- a/res/drawable-mdpi/ic_folder_parent_24dp.png +++ b/res/drawable-mdpi/ic_folder_parent_24dp.png diff --git a/res/drawable-xhdpi/ic_drawer_drafts_24dp.png b/res/drawable-xhdpi/ic_drawer_drafts_24dp.png Binary files differindex 7df7fc423..ca03046da 100644 --- a/res/drawable-xhdpi/ic_drawer_drafts_24dp.png +++ b/res/drawable-xhdpi/ic_drawer_drafts_24dp.png diff --git a/res/drawable-xhdpi/ic_drawer_folder_24dp.png b/res/drawable-xhdpi/ic_drawer_folder_24dp.png Binary files differindex 02cb6cd19..b4702e454 100644 --- a/res/drawable-xhdpi/ic_drawer_folder_24dp.png +++ b/res/drawable-xhdpi/ic_drawer_folder_24dp.png diff --git a/res/drawable-xhdpi/ic_drawer_help_24dp.png b/res/drawable-xhdpi/ic_drawer_help_24dp.png Binary files differindex 7a0d07e69..d92a4fcf2 100644 --- a/res/drawable-xhdpi/ic_drawer_help_24dp.png +++ b/res/drawable-xhdpi/ic_drawer_help_24dp.png diff --git a/res/drawable-xhdpi/ic_drawer_inbox_24dp.png b/res/drawable-xhdpi/ic_drawer_inbox_24dp.png Binary files differindex 7b70348d8..6f8eb17a7 100644 --- a/res/drawable-xhdpi/ic_drawer_inbox_24dp.png +++ b/res/drawable-xhdpi/ic_drawer_inbox_24dp.png diff --git a/res/drawable-xhdpi/ic_drawer_outbox_24dp.png b/res/drawable-xhdpi/ic_drawer_outbox_24dp.png Binary files differindex b1ddedc35..fee5e79e8 100644 --- a/res/drawable-xhdpi/ic_drawer_outbox_24dp.png +++ b/res/drawable-xhdpi/ic_drawer_outbox_24dp.png diff --git a/res/drawable-xhdpi/ic_drawer_sent_24dp.png b/res/drawable-xhdpi/ic_drawer_sent_24dp.png Binary files differindex a25f185e8..b2aeb4baf 100644 --- a/res/drawable-xhdpi/ic_drawer_sent_24dp.png +++ b/res/drawable-xhdpi/ic_drawer_sent_24dp.png diff --git a/res/drawable-xhdpi/ic_drawer_settings_24dp.png b/res/drawable-xhdpi/ic_drawer_settings_24dp.png Binary files differindex cda51d417..69a7cf05d 100644 --- a/res/drawable-xhdpi/ic_drawer_settings_24dp.png +++ b/res/drawable-xhdpi/ic_drawer_settings_24dp.png diff --git a/res/drawable-xhdpi/ic_drawer_starred_24dp.png b/res/drawable-xhdpi/ic_drawer_starred_24dp.png Binary files differindex 11d7f30a6..123c09417 100644 --- a/res/drawable-xhdpi/ic_drawer_starred_24dp.png +++ b/res/drawable-xhdpi/ic_drawer_starred_24dp.png diff --git a/res/drawable-xhdpi/ic_drawer_trash_24dp.png b/res/drawable-xhdpi/ic_drawer_trash_24dp.png Binary files differindex e1e74a5ff..d8cb09a13 100644 --- a/res/drawable-xhdpi/ic_drawer_trash_24dp.png +++ b/res/drawable-xhdpi/ic_drawer_trash_24dp.png diff --git a/res/drawable-xhdpi/ic_drawer_unread_24dp.png b/res/drawable-xhdpi/ic_drawer_unread_24dp.png Binary files differindex 7226408ae..9e0134126 100644 --- a/res/drawable-xhdpi/ic_drawer_unread_24dp.png +++ b/res/drawable-xhdpi/ic_drawer_unread_24dp.png diff --git a/res/drawable-xhdpi/ic_folder_parent_24dp.png b/res/drawable-xhdpi/ic_folder_parent_24dp.png Binary files differindex da1655c11..a4133b170 100644 --- a/res/drawable-xhdpi/ic_folder_parent_24dp.png +++ b/res/drawable-xhdpi/ic_folder_parent_24dp.png diff --git a/res/drawable-xxhdpi/ic_drawer_drafts_24dp.png b/res/drawable-xxhdpi/ic_drawer_drafts_24dp.png Binary files differindex bef77277a..b13c27fa7 100644 --- a/res/drawable-xxhdpi/ic_drawer_drafts_24dp.png +++ b/res/drawable-xxhdpi/ic_drawer_drafts_24dp.png diff --git a/res/drawable-xxhdpi/ic_drawer_folder_24dp.png b/res/drawable-xxhdpi/ic_drawer_folder_24dp.png Binary files differindex ba057d22a..c885e881e 100644 --- a/res/drawable-xxhdpi/ic_drawer_folder_24dp.png +++ b/res/drawable-xxhdpi/ic_drawer_folder_24dp.png diff --git a/res/drawable-xxhdpi/ic_drawer_help_24dp.png b/res/drawable-xxhdpi/ic_drawer_help_24dp.png Binary files differindex d00e59f1b..d9e53009e 100644 --- a/res/drawable-xxhdpi/ic_drawer_help_24dp.png +++ b/res/drawable-xxhdpi/ic_drawer_help_24dp.png diff --git a/res/drawable-xxhdpi/ic_drawer_inbox_24dp.png b/res/drawable-xxhdpi/ic_drawer_inbox_24dp.png Binary files differindex 060aa96e2..8b44898df 100644 --- a/res/drawable-xxhdpi/ic_drawer_inbox_24dp.png +++ b/res/drawable-xxhdpi/ic_drawer_inbox_24dp.png diff --git a/res/drawable-xxhdpi/ic_drawer_outbox_24dp.png b/res/drawable-xxhdpi/ic_drawer_outbox_24dp.png Binary files differindex 96261e4a6..74b799ba4 100644 --- a/res/drawable-xxhdpi/ic_drawer_outbox_24dp.png +++ b/res/drawable-xxhdpi/ic_drawer_outbox_24dp.png diff --git a/res/drawable-xxhdpi/ic_drawer_sent_24dp.png b/res/drawable-xxhdpi/ic_drawer_sent_24dp.png Binary files differindex 3ded90d50..24b0e9aa3 100644 --- a/res/drawable-xxhdpi/ic_drawer_sent_24dp.png +++ b/res/drawable-xxhdpi/ic_drawer_sent_24dp.png diff --git a/res/drawable-xxhdpi/ic_drawer_settings_24dp.png b/res/drawable-xxhdpi/ic_drawer_settings_24dp.png Binary files differindex f9b0d97d4..743ca6782 100644 --- a/res/drawable-xxhdpi/ic_drawer_settings_24dp.png +++ b/res/drawable-xxhdpi/ic_drawer_settings_24dp.png diff --git a/res/drawable-xxhdpi/ic_drawer_starred_24dp.png b/res/drawable-xxhdpi/ic_drawer_starred_24dp.png Binary files differindex 714f236f8..ceed17031 100644 --- a/res/drawable-xxhdpi/ic_drawer_starred_24dp.png +++ b/res/drawable-xxhdpi/ic_drawer_starred_24dp.png diff --git a/res/drawable-xxhdpi/ic_drawer_trash_24dp.png b/res/drawable-xxhdpi/ic_drawer_trash_24dp.png Binary files differindex 968955503..4886ab1e9 100644 --- a/res/drawable-xxhdpi/ic_drawer_trash_24dp.png +++ b/res/drawable-xxhdpi/ic_drawer_trash_24dp.png diff --git a/res/drawable-xxhdpi/ic_drawer_unread_24dp.png b/res/drawable-xxhdpi/ic_drawer_unread_24dp.png Binary files differindex 938718ac8..9b1c7e841 100644 --- a/res/drawable-xxhdpi/ic_drawer_unread_24dp.png +++ b/res/drawable-xxhdpi/ic_drawer_unread_24dp.png diff --git a/res/drawable-xxhdpi/ic_folder_parent_24dp.png b/res/drawable-xxhdpi/ic_folder_parent_24dp.png Binary files differindex 06cc04afe..19f2e4be6 100644 --- a/res/drawable-xxhdpi/ic_folder_parent_24dp.png +++ b/res/drawable-xxhdpi/ic_folder_parent_24dp.png diff --git a/res/drawable-xxxhdpi/ic_drawer_drafts_24dp.png b/res/drawable-xxxhdpi/ic_drawer_drafts_24dp.png Binary files differindex cef9c34f8..a2a58be39 100644 --- a/res/drawable-xxxhdpi/ic_drawer_drafts_24dp.png +++ b/res/drawable-xxxhdpi/ic_drawer_drafts_24dp.png diff --git a/res/drawable-xxxhdpi/ic_drawer_folder_24dp.png b/res/drawable-xxxhdpi/ic_drawer_folder_24dp.png Binary files differindex 003a6901c..1bd36266f 100644 --- a/res/drawable-xxxhdpi/ic_drawer_folder_24dp.png +++ b/res/drawable-xxxhdpi/ic_drawer_folder_24dp.png diff --git a/res/drawable-xxxhdpi/ic_drawer_help_24dp.png b/res/drawable-xxxhdpi/ic_drawer_help_24dp.png Binary files differindex fb48fbd9e..667aea889 100644 --- a/res/drawable-xxxhdpi/ic_drawer_help_24dp.png +++ b/res/drawable-xxxhdpi/ic_drawer_help_24dp.png diff --git a/res/drawable-xxxhdpi/ic_drawer_inbox_24dp.png b/res/drawable-xxxhdpi/ic_drawer_inbox_24dp.png Binary files differindex 708b41d10..17977510c 100644 --- a/res/drawable-xxxhdpi/ic_drawer_inbox_24dp.png +++ b/res/drawable-xxxhdpi/ic_drawer_inbox_24dp.png diff --git a/res/drawable-xxxhdpi/ic_drawer_outbox_24dp.png b/res/drawable-xxxhdpi/ic_drawer_outbox_24dp.png Binary files differindex 280f9c6d3..7d1ad2910 100644 --- a/res/drawable-xxxhdpi/ic_drawer_outbox_24dp.png +++ b/res/drawable-xxxhdpi/ic_drawer_outbox_24dp.png diff --git a/res/drawable-xxxhdpi/ic_drawer_sent_24dp.png b/res/drawable-xxxhdpi/ic_drawer_sent_24dp.png Binary files differindex 66af988e4..23e475e58 100644 --- a/res/drawable-xxxhdpi/ic_drawer_sent_24dp.png +++ b/res/drawable-xxxhdpi/ic_drawer_sent_24dp.png diff --git a/res/drawable-xxxhdpi/ic_drawer_settings_24dp.png b/res/drawable-xxxhdpi/ic_drawer_settings_24dp.png Binary files differindex d71793d37..83b92c4fa 100644 --- a/res/drawable-xxxhdpi/ic_drawer_settings_24dp.png +++ b/res/drawable-xxxhdpi/ic_drawer_settings_24dp.png diff --git a/res/drawable-xxxhdpi/ic_drawer_starred_24dp.png b/res/drawable-xxxhdpi/ic_drawer_starred_24dp.png Binary files differindex 242bdddf8..d1b77caf8 100644 --- a/res/drawable-xxxhdpi/ic_drawer_starred_24dp.png +++ b/res/drawable-xxxhdpi/ic_drawer_starred_24dp.png diff --git a/res/drawable-xxxhdpi/ic_drawer_trash_24dp.png b/res/drawable-xxxhdpi/ic_drawer_trash_24dp.png Binary files differindex 547f5d1b4..3bf1f7e8e 100644 --- a/res/drawable-xxxhdpi/ic_drawer_trash_24dp.png +++ b/res/drawable-xxxhdpi/ic_drawer_trash_24dp.png diff --git a/res/drawable-xxxhdpi/ic_drawer_unread_24dp.png b/res/drawable-xxxhdpi/ic_drawer_unread_24dp.png Binary files differindex f20c4bf3c..a36596d65 100644 --- a/res/drawable-xxxhdpi/ic_drawer_unread_24dp.png +++ b/res/drawable-xxxhdpi/ic_drawer_unread_24dp.png diff --git a/res/drawable-xxxhdpi/ic_folder_parent_24dp.png b/res/drawable-xxxhdpi/ic_folder_parent_24dp.png Binary files differnew file mode 100644 index 000000000..d218c6c4d --- /dev/null +++ b/res/drawable-xxxhdpi/ic_folder_parent_24dp.png diff --git a/res/layout/folder_list_blank_header.xml b/res/layout/folder_list_blank_header.xml index 2285ce265..083733898 100644 --- a/res/layout/folder_list_blank_header.xml +++ b/res/layout/folder_list_blank_header.xml @@ -15,8 +15,12 @@ See the License for the specific language governing permissions and limitations under the License. --> -<View xmlns:android="http://schemas.android.com/apk/res/android" +<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" - android:layout_height="@dimen/divider_height" - android:layout_marginBottom="8dp" - android:background="@color/folder_list_divider_color" /> + android:layout_height="wrap_content" > + <View + android:layout_width="match_parent" + android:layout_height="@dimen/divider_height" + android:layout_marginBottom="8dp" + android:background="@color/folder_list_divider_color" /> +</FrameLayout>
\ No newline at end of file diff --git a/src/com/android/mail/adapter/DrawerItem.java b/src/com/android/mail/adapter/DrawerItem.java deleted file mode 100644 index 191c365e4..000000000 --- a/src/com/android/mail/adapter/DrawerItem.java +++ /dev/null @@ -1,485 +0,0 @@ -/* - * Copyright (C) 2013 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. - */ - -package com.android.mail.adapter; - -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.TextView; - -import com.android.bitmap.BitmapCache; -import com.android.mail.R; -import com.android.mail.bitmap.ContactResolver; -import com.android.mail.providers.Account; -import com.android.mail.providers.Folder; -import com.android.mail.ui.AccountItemView; -import com.android.mail.ui.ControllableActivity; -import com.android.mail.ui.FolderItemView; -import com.android.mail.utils.FolderUri; -import com.android.mail.utils.LogTag; -import com.android.mail.utils.LogUtils; - - -/** - * An element that is shown in the {@link com.android.mail.ui.FolderListFragment}. This class is - * only used for elements that are shown in the {@link com.android.mail.ui.DrawerFragment}. - * This class is an enumeration of a few element types: Account, a folder, a recent folder, - * or a header (a resource string). A {@link DrawerItem} can only be one type and can never - * switch types. Items are created using methods like - * {@link DrawerItem#ofAccount(ControllableActivity, Account, int, boolean, BitmapCache, - * ContactResolver)}, - * {@link DrawerItem#ofWaitView(ControllableActivity)}, etc. - * - * Once created, the item can create a view using - * {@link #getView(android.view.View, android.view.ViewGroup)}. - */ -public class DrawerItem { - private static final String LOG_TAG = LogTag.getLogTag(); - public final Folder mFolder; - public final Account mAccount; - private final int mResource; - /** True if the drawer item represents the current account, false otherwise */ - private final boolean mIsSelected; - /** Either {@link #VIEW_ACCOUNT}, {@link #VIEW_FOLDER} or {@link #VIEW_HEADER} */ - public final int mType; - /** A normal folder, also a child, if a parent is specified. */ - public static final int VIEW_FOLDER = 0; - /** A text-label which serves as a header in sectioned lists. */ - public static final int VIEW_HEADER = 1; - /** A blank divider which serves as a header in sectioned lists. */ - public static final int VIEW_BLANK_HEADER = 2; - /** A spacer which serves as a footer below the last item. */ - public static final int VIEW_BOTTOM_SPACE = 3; - /** An account object, which allows switching accounts rather than folders. */ - public static final int VIEW_ACCOUNT = 4; - /** An expandable object for expanding/collapsing more of the list */ - public static final int VIEW_WAITING_FOR_SYNC = 5; - /** The value (1-indexed) of the last View type. Useful when returning the number of types. */ - private static final int LAST_FIELD = VIEW_WAITING_FOR_SYNC + 1; - - /** TODO: On adding another type, be sure to change getViewTypes() */ - - /** The parent activity */ - private final ControllableActivity mActivity; - private final LayoutInflater mInflater; - - // TODO(viki): Put all these constants in an interface. - /** - * Either {@link #FOLDER_INBOX}, {@link #FOLDER_RECENT} or {@link #FOLDER_OTHER} when - * {@link #mType} is {@link #VIEW_FOLDER}, or an {@link #ACCOUNT} in the case of - * accounts, and {@link #INERT_HEADER} otherwise. - */ - public final int mFolderType; - /** Non existent item or folder type not yet set */ - public static final int UNSET = 0; - /** An unclickable text-header visually separating the different types. */ - public static final int INERT_HEADER = 0; - /** An inbox folder: Inbox, ...*/ - public static final int FOLDER_INBOX = 1; - /** A folder from whom a conversation was recently viewed */ - public static final int FOLDER_RECENT = 2; - /** A non-inbox folder that is shown in the "everything else" group. */ - public static final int FOLDER_OTHER = 3; - /** An entry for the accounts the user has on the device. */ - public static final int ACCOUNT = 4; - - /** True if this view is enabled, false otherwise. */ - private final boolean mIsEnabled; - - private BitmapCache mImagesCache; - private ContactResolver mContactResolver; - - @Override - public String toString() { - switch(mType) { - case VIEW_FOLDER: - return folderToString(); - case VIEW_HEADER: - return headerToString(); - case VIEW_BLANK_HEADER: - return blankHeaderToString(); - case VIEW_BOTTOM_SPACE: - return bottomSpaceToString(); - case VIEW_ACCOUNT: - return accountToString(); - case VIEW_WAITING_FOR_SYNC: - return waitToString(); - } - // Should never come here. - return null; - } - - /** - * Creates a drawer item with every instance variable specified. - * - * @param type the type of the item. This must be a VIEW_* element - * @param activity the underlying activity - * @param folder a non-null folder, if this is a folder type - * @param folderType the type of the folder. For folders this is: - * {@link #FOLDER_INBOX}, {@link #FOLDER_RECENT}, - * {@link #FOLDER_OTHER}, or for non-folders this is - * {@link #ACCOUNT}, or {@link #INERT_HEADER} - * @param account the account object, for an account drawer element - * @param resource either the string resource for a header, or the unread - * count for an account. - * @param isCurrentAccount true if this item is the current account - */ - private DrawerItem(int type, ControllableActivity activity, Folder folder, int folderType, - Account account, int resource, boolean isCurrentAccount, BitmapCache cache, - ContactResolver contactResolver) { - mActivity = activity; - mFolder = folder; - mFolderType = folderType; - mAccount = account; - mResource = resource; - mIsSelected = isCurrentAccount; - mInflater = LayoutInflater.from(activity.getActivityContext()); - mType = type; - mIsEnabled = calculateEnabled(); - mImagesCache = cache; - mContactResolver = contactResolver; - } - - /** - * Create a folder item with the given type. - * - * @param activity the underlying activity - * @param folder a folder that this item represents - * @param folderType one of {@link #FOLDER_INBOX}, {@link #FOLDER_RECENT} or - * {@link #FOLDER_OTHER} - * @return a drawer item for the folder. - */ - public static DrawerItem ofFolder(ControllableActivity activity, Folder folder, - int folderType) { - return new DrawerItem(VIEW_FOLDER, activity, folder, folderType, null, -1, false, - null, null); - } - - private String folderToString() { - final StringBuilder sb = new StringBuilder("[DrawerItem "); - sb.append(" VIEW_FOLDER "); - sb.append(", mFolder="); - sb.append(mFolder); - sb.append(", mFolderType="); - sb.append(mFolderType); - sb.append("]"); - return sb.toString(); - } - - /** - * Creates an item from an account. - * @param activity the underlying activity - * @param account the account to create a drawer item for - * @param unreadCount the unread count of the account, pass zero if - * @param isCurrentAccount true if the account is the current account, false otherwise - * @return a drawer item for the account. - */ - public static DrawerItem ofAccount(ControllableActivity activity, Account account, - int unreadCount, boolean isCurrentAccount, BitmapCache cache, - ContactResolver contactResolver) { - return new DrawerItem(VIEW_ACCOUNT, activity, null, ACCOUNT, account, unreadCount, - isCurrentAccount, cache, contactResolver); - } - - private String accountToString() { - final StringBuilder sb = new StringBuilder("[DrawerItem "); - sb.append(" VIEW_ACCOUNT "); - sb.append(", mAccount="); - sb.append(mAccount); - sb.append("]"); - return sb.toString(); - } - - /** - * Create a header item with a string resource. - * - * @param activity the underlying activity - * @param resource the string resource: R.string.all_folders_heading - * @return a drawer item for the header. - */ - public static DrawerItem ofHeader(ControllableActivity activity, int resource) { - return new DrawerItem(VIEW_HEADER, activity, null, INERT_HEADER, null, resource, false, - null, null); - } - - private String headerToString() { - final StringBuilder sb = new StringBuilder("[DrawerItem "); - sb.append(" VIEW_HEADER "); - sb.append(", mResource="); - sb.append(mResource); - sb.append("]"); - return sb.toString(); - } - - public static DrawerItem ofBlankHeader(ControllableActivity activity) { - return new DrawerItem(VIEW_BLANK_HEADER, activity, null, INERT_HEADER, null, 0, false, null, - null); - } - - private String blankHeaderToString() { - return "[DrawerItem VIEW_BLANK_HEADER]"; - } - - public static DrawerItem ofBottomSpace(ControllableActivity activity) { - return new DrawerItem(VIEW_BOTTOM_SPACE, activity, null, INERT_HEADER, null, 0, false, null, - null); - } - - private String bottomSpaceToString() { - return "[DrawerItem VIEW_BOTTOM_SPACE]"; - } - - /** - * Create a "waiting for initialization" item. - * - * @param activity the underlying activity - * @return a drawer item with an indeterminate progress indicator. - */ - public static DrawerItem ofWaitView(ControllableActivity activity) { - return new DrawerItem(VIEW_WAITING_FOR_SYNC, activity, null, INERT_HEADER, null, -1, false, - null, null); - } - - private static String waitToString() { - return "[DrawerItem VIEW_WAITING_FOR_SYNC]"; - } - - /** - * Returns a view for the given item. The method signature is identical to that required by a - * {@link android.widget.ListAdapter#getView(int, android.view.View, android.view.ViewGroup)}. - */ - public View getView(View convertView, ViewGroup parent) { - final View result; - switch (mType) { - case VIEW_FOLDER: - result = getFolderView(convertView, parent); - break; - case VIEW_HEADER: - result = getHeaderView(convertView, parent); - break; - case VIEW_BLANK_HEADER: - result = getBlankHeaderView(convertView, parent); - break; - case VIEW_BOTTOM_SPACE: - result = getBottomSpaceView(convertView, parent); - break; - case VIEW_ACCOUNT: - result = getAccountView(convertView, parent); - break; - case VIEW_WAITING_FOR_SYNC: - result = getEmptyView(convertView, parent); - break; - default: - LogUtils.wtf(LOG_TAG, "DrawerItem.getView(%d) for an invalid type!", mType); - result = null; - } - return result; - } - - /** - * Book-keeping for how many different view types there are. Be sure to - * increment this appropriately once adding more types as drawer items - * @return number of different types of view items - */ - public static int getViewTypes() { - return LAST_FIELD; - } - - /** - * Returns whether this view is enabled or not. An enabled view is one that accepts user taps - * and acts upon them. - * @return true if this view is enabled, false otherwise. - */ - public boolean isItemEnabled() { - return mIsEnabled; - } - - /** Calculate whether the item is enabled */ - private boolean calculateEnabled() { - switch (mType) { - case VIEW_HEADER: - case VIEW_BLANK_HEADER: - case VIEW_BOTTOM_SPACE: - // Headers are never enabled. - return false; - case VIEW_FOLDER: - // Folders are always enabled. - return true; - case VIEW_ACCOUNT: - // Accounts are always enabled. - return true; - case VIEW_WAITING_FOR_SYNC: - // Waiting for sync cannot be tapped, so never enabled. - return false; - default: - LogUtils.wtf(LOG_TAG, "DrawerItem.isItemEnabled() for invalid type %d", mType); - return false; - } - } - - /** - * Returns whether this view is highlighted or not. - * - * - * @param currentFolder The current folder, according to the - * {@link com.android.mail.ui.FolderListFragment} - * @param currentType The type of the current folder. We want to only highlight a folder once. - * A folder might be in two places at once: in "All Folders", and in - * "Recent Folder". Valid types of selected folders are : - * {@link DrawerItem#FOLDER_INBOX}, {@link DrawerItem#FOLDER_RECENT} or - * {@link DrawerItem#FOLDER_OTHER}, or {@link DrawerItem#UNSET}. - - * @return true if this DrawerItem results in a view that is highlighted (this DrawerItem is - * the current folder. - */ - public boolean isHighlighted(FolderUri currentFolder, int currentType) { - switch (mType) { - case VIEW_HEADER: - case VIEW_BLANK_HEADER: - case VIEW_BOTTOM_SPACE: - // Headers are never highlighted - return false; - case VIEW_FOLDER: - // True if folder types and URIs are the same - if (currentFolder != null && mFolder != null && mFolder.folderUri != null) { - return (mFolderType == currentType) && mFolder.folderUri.equals(currentFolder); - } - return false; - case VIEW_ACCOUNT: - // Accounts are never highlighted - return false; - case VIEW_WAITING_FOR_SYNC: - // Waiting for sync cannot be tapped, so never highlighted. - return false; - default: - LogUtils.wtf(LOG_TAG, "DrawerItem.isHighlighted() for invalid type %d", mType); - return false; - } - } - - /** - * Return a view for an account object. - * - * @param convertView a view, possibly null, to be recycled. - * @param parent the parent viewgroup to attach to. - * @return a view to display at this position. - */ - private View getAccountView(View convertView, ViewGroup parent) { - final AccountItemView accountItemView; - if (convertView != null) { - accountItemView = (AccountItemView) convertView; - } else { - accountItemView = - (AccountItemView) mInflater.inflate(R.layout.account_item, parent, false); - } - accountItemView.bind(mActivity.getActivityContext(), mAccount, mIsSelected, mImagesCache, - mContactResolver); - return accountItemView; - } - - /** - * Returns a text divider between divisions. - * - * @param convertView a previous view, perhaps null - * @param parent the parent of this view - * @return a text header at the given position. - */ - private View getHeaderView(View convertView, ViewGroup parent) { - final View headerView; - if (convertView != null) { - headerView = convertView; - } else { - headerView = mInflater.inflate(R.layout.folder_list_header, parent, false); - } - final TextView textView = (TextView) headerView.findViewById(R.id.header_text); - textView.setText(mResource); - return headerView; - } - - /** - * Returns a blank divider - * - * @param convertView A previous view, perhaps null - * @param parent the parent of this view - * @return a blank header - */ - private View getBlankHeaderView(View convertView, ViewGroup parent) { - final View blankHeaderView; - if (convertView != null) { - blankHeaderView = convertView; - } else { - blankHeaderView = mInflater.inflate(R.layout.folder_list_blank_header, parent, false); - } - return blankHeaderView; - } - - /** - * Returns a blank spacer - * - * @param convertView A previous view, perhaps null - * @param parent the parent of this view - * @return a blank spacer - */ - private View getBottomSpaceView(View convertView, ViewGroup parent) { - final View blankHeaderView; - if (convertView != null) { - blankHeaderView = convertView; - } else { - blankHeaderView = mInflater.inflate(R.layout.folder_list_bottom_space, parent, false); - } - return blankHeaderView; - } - - /** - * Return a folder: either a parent folder or a normal (child or flat) - * folder. - * - * @param convertView a view, possibly null, to be recycled. - * @return a view showing a folder at the given position. - */ - private View getFolderView(View convertView, ViewGroup parent) { - final FolderItemView folderItemView; - if (convertView != null) { - folderItemView = (FolderItemView) convertView; - } else { - folderItemView = - (FolderItemView) mInflater.inflate(R.layout.folder_item, parent, false); - } - folderItemView.bind(mFolder, null); - folderItemView.setIcon(mFolder); - return folderItemView; - } - - /** - * Return a view for the 'Waiting for sync' item with the indeterminate progress indicator. - * - * @param convertView a view, possibly null, to be recycled. - * @param parent the parent hosting this view. - * @return a view for "Waiting for sync..." at given position. - */ - private View getEmptyView(View convertView, ViewGroup parent) { - final ViewGroup emptyView; - if (convertView != null) { - emptyView = (ViewGroup) convertView; - } else { - emptyView = (ViewGroup) mInflater.inflate(R.layout.drawer_empty_view, parent, false); - } - return emptyView; - } - -} - diff --git a/src/com/android/mail/drawer/AccountDrawerItem.java b/src/com/android/mail/drawer/AccountDrawerItem.java new file mode 100644 index 000000000..cdd49327d --- /dev/null +++ b/src/com/android/mail/drawer/AccountDrawerItem.java @@ -0,0 +1,86 @@ +/* + * Copyright (C) 2014 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. + */ + +package com.android.mail.drawer; + +import android.view.View; +import android.view.ViewGroup; + +import com.android.bitmap.BitmapCache; +import com.android.mail.R; +import com.android.mail.bitmap.ContactResolver; +import com.android.mail.providers.Account; +import com.android.mail.ui.AccountItemView; +import com.android.mail.ui.ControllableActivity; +import com.android.mail.utils.FolderUri; + +class AccountDrawerItem extends DrawerItem { + /** True if the drawer item represents the current account, false otherwise */ + private final boolean mIsSelected; + private final BitmapCache mImagesCache; + private final ContactResolver mContactResolver; + + AccountDrawerItem(ControllableActivity activity, Account account, + int unreadCount, boolean isCurrentAccount, BitmapCache cache, + ContactResolver contactResolver) { + super(activity, null, NONFOLDER_ITEM, account); + mIsSelected = isCurrentAccount; + mImagesCache = cache; + mContactResolver = contactResolver; + // TODO: Unread count should eventually percolate through to the account switcher + } + + @Override + public String toString() { + return "[DrawerItem VIEW_ACCOUNT, mAccount=" + mAccount + "]"; + } + + /** + * Return a view for an account object. + * + * @param convertView a view, possibly null, to be recycled. + * @param parent the parent viewgroup to attach to. + * @return a view to display at this position. + */ + @Override + public View getView(View convertView, ViewGroup parent) { + final AccountItemView accountItemView; + if (convertView != null) { + accountItemView = (AccountItemView) convertView; + } else { + accountItemView = + (AccountItemView) mInflater.inflate(R.layout.account_item, parent, false); + } + accountItemView.bind(mActivity.getActivityContext(), mAccount, mIsSelected, + mImagesCache, mContactResolver); + return accountItemView; + } + + @Override + public boolean isHighlighted(FolderUri currentFolder, int currentType) { + return false; + } + + @Override + public boolean isItemEnabled() { + return true; + } + + @Override + public @DrawerItemType int getType() { + return VIEW_ACCOUNT; + } +} diff --git a/src/com/android/mail/drawer/BlankHeaderDrawerItem.java b/src/com/android/mail/drawer/BlankHeaderDrawerItem.java new file mode 100644 index 000000000..35abcfc36 --- /dev/null +++ b/src/com/android/mail/drawer/BlankHeaderDrawerItem.java @@ -0,0 +1,69 @@ +/* + * Copyright (C) 2014 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. + */ + +package com.android.mail.drawer; + +import android.view.View; +import android.view.ViewGroup; + +import com.android.mail.R; +import com.android.mail.ui.ControllableActivity; +import com.android.mail.utils.FolderUri; + +class BlankHeaderDrawerItem extends DrawerItem { + BlankHeaderDrawerItem(ControllableActivity activity) { + super(activity, null, NONFOLDER_ITEM, null); + } + + @Override + public String toString() { + return "[DrawerItem VIEW_BLANK_HEADER]"; + } + + /** + * Returns a blank divider + * + * @param convertView A previous view, perhaps null + * @param parent the parent of this view + * @return a blank header + */ + @Override + public View getView(View convertView, ViewGroup parent) { + final View blankHeaderView; + if (convertView != null) { + blankHeaderView = convertView; + } else { + blankHeaderView = mInflater.inflate(R.layout.folder_list_blank_header, parent, + false); + } + return blankHeaderView; + } + + @Override + public boolean isHighlighted(FolderUri currentFolder, int currentType) { + return false; + } + + @Override + public boolean isItemEnabled() { + return false; + } + + @Override + public @DrawerItemType int getType() { + return VIEW_BLANK_HEADER; + } +} diff --git a/src/com/android/mail/drawer/BottomSpaceDrawerItem.java b/src/com/android/mail/drawer/BottomSpaceDrawerItem.java new file mode 100644 index 000000000..9d8ef5ee1 --- /dev/null +++ b/src/com/android/mail/drawer/BottomSpaceDrawerItem.java @@ -0,0 +1,69 @@ +/* + * Copyright (C) 2014 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. + */ + +package com.android.mail.drawer; + +import android.view.View; +import android.view.ViewGroup; + +import com.android.mail.R; +import com.android.mail.ui.ControllableActivity; +import com.android.mail.utils.FolderUri; + +class BottomSpaceDrawerItem extends DrawerItem { + BottomSpaceDrawerItem(ControllableActivity activity) { + super(activity, null, NONFOLDER_ITEM, null); + } + + @Override + public String toString() { + return "[DrawerItem VIEW_BOTTOM_SPACE]"; + } + + /** + * Returns a blank spacer + * + * @param convertView A previous view, perhaps null + * @param parent the parent of this view + * @return a blank spacer + */ + @Override + public View getView(View convertView, ViewGroup parent) { + final View blankHeaderView; + if (convertView != null) { + blankHeaderView = convertView; + } else { + blankHeaderView = mInflater.inflate(R.layout.folder_list_bottom_space, parent, + false); + } + return blankHeaderView; + } + + @Override + public boolean isHighlighted(FolderUri currentFolder, int currentType) { + return false; + } + + @Override + public boolean isItemEnabled() { + return false; + } + + @Override + public @DrawerItemType int getType() { + return VIEW_BOTTOM_SPACE; + } +} diff --git a/src/com/android/mail/drawer/DrawerItem.java b/src/com/android/mail/drawer/DrawerItem.java new file mode 100644 index 000000000..a360f1282 --- /dev/null +++ b/src/com/android/mail/drawer/DrawerItem.java @@ -0,0 +1,231 @@ +/* + * Copyright (C) 2013 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. + */ + +package com.android.mail.drawer; + +import android.support.annotation.IntDef; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import com.android.bitmap.BitmapCache; +import com.android.mail.bitmap.ContactResolver; +import com.android.mail.providers.Account; +import com.android.mail.providers.Folder; +import com.android.mail.ui.ControllableActivity; +import com.android.mail.ui.FolderListFragment; +import com.android.mail.utils.FolderUri; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + + +/** + * An element that is shown in the {@link com.android.mail.ui.FolderListFragment}. This class is + * only used for elements that are shown in the {@link com.android.mail.ui.DrawerFragment}. + * This class is an enumeration of a few element types: Account, a folder, a recent folder, + * or a header (a resource string). A {@link DrawerItem} can only be one type and can never + * switch types. Items are created using methods like + * {@link DrawerItem#ofAccount(ControllableActivity, Account, int, boolean, BitmapCache, + * ContactResolver)}, + * {@link DrawerItem#ofWaitView(ControllableActivity)}, etc. + * + * Once created, the item can create a view using + * {@link #getView(android.view.View, android.view.ViewGroup)}. + */ +public abstract class DrawerItem { + public final Folder mFolder; + public final Account mAccount; + + /** These are view types for view recycling purposes */ + @Retention(RetentionPolicy.CLASS) + @IntDef({VIEW_FOLDER, VIEW_HEADER, VIEW_BLANK_HEADER, VIEW_BOTTOM_SPACE, VIEW_ACCOUNT, + VIEW_WAITING_FOR_SYNC, VIEW_FOOTER_HELP, VIEW_FOOTER_SETTINGS}) + public @interface DrawerItemType {} + /** A normal folder, also a child, if a parent is specified. */ + public static final int VIEW_FOLDER = 0; + /** A text-label which serves as a header in sectioned lists. */ + public static final int VIEW_HEADER = 1; + /** A blank divider which serves as a header in sectioned lists. */ + public static final int VIEW_BLANK_HEADER = 2; + /** A spacer which serves as a footer below the last item. */ + public static final int VIEW_BOTTOM_SPACE = 3; + /** An account object, which allows switching accounts rather than folders. */ + public static final int VIEW_ACCOUNT = 4; + /** An expandable object for expanding/collapsing more of the list */ + public static final int VIEW_WAITING_FOR_SYNC = 5; + /** A footer item for Help */ + public static final int VIEW_FOOTER_HELP = 6; + /** A footer item for Settings */ + public static final int VIEW_FOOTER_SETTINGS = 7; + /** The value (1-indexed) of the last View type. Useful when returning the number of types. */ + private static final int LAST_FIELD = VIEW_FOOTER_SETTINGS + 1; + + /** The parent activity */ + protected final ControllableActivity mActivity; + protected final LayoutInflater mInflater; + + /** + * These values determine the behavior of the drawer items. + * + * Either {@link #FOLDER_INBOX}, {@link #FOLDER_RECENT} or {@link #FOLDER_OTHER} when + * {@link #getType()} is {@link #VIEW_FOLDER}, or {@link #NONFOLDER_ITEM} otherwise. + */ + @Retention(RetentionPolicy.CLASS) + @IntDef({UNSET, NONFOLDER_ITEM, FOLDER_INBOX, FOLDER_RECENT, FOLDER_OTHER}) + public @interface DrawerItemCategory {} + public final @DrawerItemCategory int mItemCategory; + /** Non existent item or folder type not yet set */ + public static final int UNSET = 0; + /** An unclickable text-header visually separating the different types. */ + public static final int NONFOLDER_ITEM = 0; + /** An inbox folder: Inbox, ...*/ + public static final int FOLDER_INBOX = 1; + /** A folder from whom a conversation was recently viewed */ + public static final int FOLDER_RECENT = 2; + /** A non-inbox folder that is shown in the "everything else" group. */ + public static final int FOLDER_OTHER = 3; + + /** + * Creates a drawer item with every instance variable specified. + * + * @param activity the underlying activity + * @param folder a non-null folder, if this is a folder type + * @param itemCategory the type of the folder. For folders this is: + * {@link #FOLDER_INBOX}, {@link #FOLDER_RECENT}, {@link #FOLDER_OTHER}, + * or for non-folders this is {@link #NONFOLDER_ITEM} + * @param account the account object, for an account drawer element + */ + protected DrawerItem(ControllableActivity activity, Folder folder, + @DrawerItemCategory int itemCategory, Account account) { + mActivity = activity; + mFolder = folder; + mItemCategory = itemCategory; + mAccount = account; + mInflater = LayoutInflater.from(activity.getActivityContext()); + } + + /** + * Create a folder item with the given type. + * + * @param activity the underlying activity + * @param folder a folder that this item represents + * @param itemCategory one of {@link #FOLDER_INBOX}, {@link #FOLDER_RECENT} or + * {@link #FOLDER_OTHER} + * @return a drawer item for the folder. + */ + public static DrawerItem ofFolder(ControllableActivity activity, Folder folder, + @DrawerItemCategory int itemCategory) { + return new FolderDrawerItem(activity, folder, itemCategory); + } + + /** + * Creates an item from an account. + * @param activity the underlying activity + * @param account the account to create a drawer item for + * @param unreadCount the unread count of the account, pass zero if + * @param isCurrentAccount true if the account is the current account, false otherwise + * @return a drawer item for the account. + */ + public static DrawerItem ofAccount(ControllableActivity activity, Account account, + int unreadCount, boolean isCurrentAccount, BitmapCache cache, + ContactResolver contactResolver) { + return new AccountDrawerItem(activity, account, unreadCount, isCurrentAccount, cache, + contactResolver); + } + + /** + * Create a header item with a string resource. + * + * @param activity the underlying activity + * @param resource the string resource: R.string.all_folders_heading + * @return a drawer item for the header. + */ + public static DrawerItem ofHeader(ControllableActivity activity, int resource) { + return new HeaderDrawerItem(activity, resource); + } + + public static DrawerItem ofBlankHeader(ControllableActivity activity) { + return new BlankHeaderDrawerItem(activity); + } + + public static DrawerItem ofBottomSpace(ControllableActivity activity) { + return new BottomSpaceDrawerItem(activity); + } + + /** + * Create a "waiting for initialization" item. + * + * @param activity the underlying activity + * @return a drawer item with an indeterminate progress indicator. + */ + public static DrawerItem ofWaitView(ControllableActivity activity) { + return new WaitViewDrawerItem(activity); + } + + public static DrawerItem ofHelpItem(ControllableActivity activity, Account account, + FolderListFragment.DrawerStateListener drawerListener) { + return new HelpItem(activity, account, drawerListener); + } + + public static DrawerItem ofSettingsItem(ControllableActivity activity, Account account, + FolderListFragment.DrawerStateListener drawerListener) { + return new SettingsItem(activity, account, drawerListener); + } + + /** + * Returns a view for the given item. The method signature is identical to that required by a + * {@link android.widget.ListAdapter#getView(int, android.view.View, android.view.ViewGroup)}. + */ + public abstract View getView(View convertView, ViewGroup parent); + + /** + * Book-keeping for how many different view types there are. + * @return number of different types of view items + */ + public static int getViewTypeCount() { + return LAST_FIELD; + } + + /** + * Returns whether this view is enabled or not. An enabled view is one that accepts user taps + * and acts upon them. + * @return true if this view is enabled, false otherwise. + */ + public abstract boolean isItemEnabled(); + + /** + * Returns whether this view is highlighted or not. + * + * + * @param currentFolder The current folder, according to the + * {@link com.android.mail.ui.FolderListFragment} + * @param currentType The type of the current folder. We want to only highlight a folder once. + * A folder might be in two places at once: in "All Folders", and in + * "Recent Folder". Valid types of selected folders are : + * {@link DrawerItem#FOLDER_INBOX}, {@link DrawerItem#FOLDER_RECENT} or + * {@link DrawerItem#FOLDER_OTHER}, or {@link DrawerItem#UNSET}. + + * @return true if this DrawerItem results in a view that is highlighted (this DrawerItem is + * the current folder. + */ + public abstract boolean isHighlighted(FolderUri currentFolder, int currentType); + + public abstract @DrawerItemType int getType(); + + public void onClick(View v) {} +} + diff --git a/src/com/android/mail/drawer/FolderDrawerItem.java b/src/com/android/mail/drawer/FolderDrawerItem.java new file mode 100644 index 000000000..823d686c1 --- /dev/null +++ b/src/com/android/mail/drawer/FolderDrawerItem.java @@ -0,0 +1,79 @@ +/* + * Copyright (C) 2014 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. + */ + +package com.android.mail.drawer; + +import android.view.View; +import android.view.ViewGroup; + +import com.android.mail.R; +import com.android.mail.providers.Folder; +import com.android.mail.ui.ControllableActivity; +import com.android.mail.ui.FolderItemView; +import com.android.mail.utils.FolderUri; + +class FolderDrawerItem extends DrawerItem { + FolderDrawerItem(ControllableActivity activity, Folder folder, + @DrawerItemCategory int folderCategory) { + super(activity, folder, folderCategory, null); + } + + @Override + public String toString() { + return "[DrawerItem VIEW_FOLDER, mFolder=" + mFolder + ", mItemCategory=" + + mItemCategory + "]"; + } + + /** + * Return a folder: either a parent folder or a normal (child or flat) + * folder. + * + * @param convertView a view, possibly null, to be recycled. + * @return a view showing a folder at the given position. + */ + @Override + public View getView(View convertView, ViewGroup parent) { + final FolderItemView folderItemView; + if (convertView != null) { + folderItemView = (FolderItemView) convertView; + } else { + folderItemView = + (FolderItemView) mInflater.inflate(R.layout.folder_item, parent, false); + } + folderItemView.bind(mFolder, null /* parentUri */); + folderItemView.setIcon(mFolder); + return folderItemView; + } + + @Override + public boolean isHighlighted(FolderUri currentFolder, int currentType) { + // True if folder types and URIs are the same + if (currentFolder != null && mFolder != null && mFolder.folderUri != null) { + return (mItemCategory == currentType) && mFolder.folderUri.equals(currentFolder); + } + return false; + } + + @Override + public boolean isItemEnabled() { + return true; + } + + @Override + public @DrawerItemType int getType() { + return VIEW_FOLDER; + } +} diff --git a/src/com/android/mail/drawer/FooterItem.java b/src/com/android/mail/drawer/FooterItem.java new file mode 100644 index 000000000..51bebd3d1 --- /dev/null +++ b/src/com/android/mail/drawer/FooterItem.java @@ -0,0 +1,108 @@ +/* + * Copyright (C) 2014 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. + */ + +package com.android.mail.drawer; + +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageView; +import android.widget.TextView; + +import com.android.mail.R; +import com.android.mail.providers.Account; +import com.android.mail.ui.ControllableActivity; +import com.android.mail.ui.DrawerController; +import com.android.mail.ui.FolderListFragment; + +/** + * The base class of all footer items. Subclasses must fill in the logic of + * {@link #onFooterClicked()} which contains the behavior when the item is selected. + */ +public abstract class FooterItem extends DrawerItem implements View.OnClickListener { + + private final FolderListFragment.DrawerStateListener mDrawerListener; + private final int mImageResourceId; + private final int mTextResourceId; + + FooterItem(ControllableActivity activity, Account account, + FolderListFragment.DrawerStateListener drawerListener, + final int imageResourceId, final int textResourceId) { + super(activity, null, NONFOLDER_ITEM, account); + mDrawerListener = drawerListener; + mImageResourceId = imageResourceId; + mTextResourceId = textResourceId; + } + + private int getImageResourceId() { + return mImageResourceId; + } + + private int getTextResourceId() { + return mTextResourceId; + } + + /** + * Executes the behavior associated with this footer item.<br> + * <br> + * WARNING: you probably don't want to call this directly; use {@link #onClick(View)} instead. + * This method actually performs the action, and its execution may be deferred from when the + * 'click' happens so we can smoothly close the drawer beforehand. + */ + public abstract void onFooterClicked(); + + @Override + public final void onClick(View v) { + final DrawerController dc = mActivity.getDrawerController(); + if (dc.isDrawerEnabled()) { + // close the drawer and defer handling the click until onDrawerClosed + mActivity.getAccountController().closeDrawer(false /* hasNewFolderOrAccount */, + null /* nextAccount */, null /* nextFolder */); + mDrawerListener.setPendingFooterClick(this); + } else { + onFooterClicked(); + } + } + + /** + * For analytics + * @return label for analytics event + */ + protected String getEventLabel() { + return "drawer_footer/" + mActivity.getViewMode().getModeString(); + } + + @Override + public View getView(View convertView, ViewGroup parent) { + final ViewGroup footerItemView; + if (convertView != null) { + footerItemView = (ViewGroup) convertView; + } else { + footerItemView = + (ViewGroup) mInflater.inflate(R.layout.drawer_footer_item, parent, false); + } + + // adjust the text of the footer item + final TextView textView = (TextView) footerItemView. + findViewById(R.id.drawer_footer_text); + textView.setText(getTextResourceId()); + + // adjust the icon of the footer item + final ImageView imageView = (ImageView) footerItemView. + findViewById(R.id.drawer_footer_image); + imageView.setImageResource(getImageResourceId()); + return footerItemView; + } +} diff --git a/src/com/android/mail/drawer/HeaderDrawerItem.java b/src/com/android/mail/drawer/HeaderDrawerItem.java new file mode 100644 index 000000000..e21daf1e9 --- /dev/null +++ b/src/com/android/mail/drawer/HeaderDrawerItem.java @@ -0,0 +1,74 @@ +/* + * Copyright (C) 2014 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. + */ + +package com.android.mail.drawer; + +import android.view.View; +import android.view.ViewGroup; +import android.widget.TextView; + +import com.android.mail.R; +import com.android.mail.ui.ControllableActivity; +import com.android.mail.utils.FolderUri; + +class HeaderDrawerItem extends DrawerItem { + private final int mResource; + + HeaderDrawerItem(ControllableActivity activity, int resource) { + super(activity, null, NONFOLDER_ITEM, null); + mResource = resource; + } + + @Override + public String toString() { + return "[DrawerItem VIEW_HEADER, mResource=" + mResource + "]"; + } + + /** + * Returns a text divider between divisions. + * + * @param convertView a previous view, perhaps null + * @param parent the parent of this view + * @return a text header at the given position. + */ + @Override + public View getView(View convertView, ViewGroup parent) { + final View headerView; + if (convertView != null) { + headerView = convertView; + } else { + headerView = mInflater.inflate(R.layout.folder_list_header, parent, false); + } + final TextView textView = (TextView) headerView.findViewById(R.id.header_text); + textView.setText(mResource); + return headerView; + } + + @Override + public boolean isHighlighted(FolderUri currentFolder, int currentType) { + return false; + } + + @Override + public boolean isItemEnabled() { + return false; + } + + @Override + public @DrawerItemType int getType() { + return VIEW_HEADER; + } +} diff --git a/src/com/android/mail/drawer/HelpItem.java b/src/com/android/mail/drawer/HelpItem.java new file mode 100644 index 000000000..651b7d3c0 --- /dev/null +++ b/src/com/android/mail/drawer/HelpItem.java @@ -0,0 +1,60 @@ +/* + * Copyright (C) 2014 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. + */ + +package com.android.mail.drawer; + +import com.android.mail.R; +import com.android.mail.analytics.Analytics; +import com.android.mail.providers.Account; +import com.android.mail.ui.ControllableActivity; +import com.android.mail.ui.FolderListFragment; +import com.android.mail.ui.ViewMode; +import com.android.mail.utils.FolderUri; + +class HelpItem extends FooterItem { + HelpItem(ControllableActivity activity, Account account, + FolderListFragment.DrawerStateListener drawerListener) { + super(activity, account, drawerListener, + R.drawable.ic_drawer_help_24dp, R.string.help_and_feedback); + } + + @Override + public void onFooterClicked() { + Analytics.getInstance().sendMenuItemEvent(Analytics.EVENT_CATEGORY_MENU_ITEM, + R.id.help_info_menu_item, getEventLabel(), 0); + mActivity.showHelp(mAccount, ViewMode.CONVERSATION_LIST); + } + + @Override + public int getType() { + return VIEW_FOOTER_HELP; + } + + @Override + public String toString() { + return "[FooterItem VIEW_HELP_ITEM]"; + } + + @Override + public boolean isItemEnabled() { + return false; + } + + @Override + public boolean isHighlighted(FolderUri currentFolder, int currentType) { + return false; + } +} diff --git a/src/com/android/mail/drawer/SettingsItem.java b/src/com/android/mail/drawer/SettingsItem.java new file mode 100644 index 000000000..07d3fca5d --- /dev/null +++ b/src/com/android/mail/drawer/SettingsItem.java @@ -0,0 +1,60 @@ +/* + * Copyright (C) 2014 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. + */ + +package com.android.mail.drawer; + +import com.android.mail.R; +import com.android.mail.analytics.Analytics; +import com.android.mail.providers.Account; +import com.android.mail.ui.ControllableActivity; +import com.android.mail.ui.FolderListFragment; +import com.android.mail.utils.FolderUri; +import com.android.mail.utils.Utils; + +class SettingsItem extends FooterItem { + SettingsItem(ControllableActivity activity, Account account, + FolderListFragment.DrawerStateListener drawerListener) { + super(activity, account, drawerListener, + R.drawable.ic_drawer_settings_24dp, R.string.menu_settings); + } + + @Override + public void onFooterClicked() { + Analytics.getInstance().sendMenuItemEvent(Analytics.EVENT_CATEGORY_MENU_ITEM, + R.id.settings, getEventLabel(), 0); + Utils.showSettings(mActivity.getActivityContext(), mAccount); + } + + @Override + public int getType() { + return VIEW_FOOTER_SETTINGS; + } + + @Override + public boolean isHighlighted(FolderUri currentFolder, int currentType) { + return false; + } + + @Override + public boolean isItemEnabled() { + return false; + } + + @Override + public String toString() { + return "[FooterItem VIEW_SETTINGS_ITEM]"; + } +} diff --git a/src/com/android/mail/drawer/WaitViewDrawerItem.java b/src/com/android/mail/drawer/WaitViewDrawerItem.java new file mode 100644 index 000000000..ba9fc19d0 --- /dev/null +++ b/src/com/android/mail/drawer/WaitViewDrawerItem.java @@ -0,0 +1,68 @@ +/* + * Copyright (C) 2014 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. + */ + +package com.android.mail.drawer; + +import android.view.View; +import android.view.ViewGroup; + +import com.android.mail.R; +import com.android.mail.ui.ControllableActivity; +import com.android.mail.utils.FolderUri; + +class WaitViewDrawerItem extends DrawerItem { + WaitViewDrawerItem(ControllableActivity activity) { + super(activity, null, NONFOLDER_ITEM, null); + } + + @Override + public String toString() { + return "[DrawerItem VIEW_WAITING_FOR_SYNC]"; + } + + /** + * Return a view for the 'Waiting for sync' item with the indeterminate progress indicator. + * + * @param convertView a view, possibly null, to be recycled. + * @param parent the parent hosting this view. + * @return a view for "Waiting for sync..." at given position. + */ + @Override + public View getView(View convertView, ViewGroup parent) { + final ViewGroup emptyView; + if (convertView != null) { + emptyView = (ViewGroup) convertView; + } else { + emptyView = (ViewGroup) mInflater.inflate(R.layout.drawer_empty_view, parent, false); + } + return emptyView; + } + + @Override + public boolean isHighlighted(FolderUri currentFolder, int currentType) { + return false; + } + + @Override + public boolean isItemEnabled() { + return false; + } + + @Override + public @DrawerItemType int getType() { + return VIEW_WAITING_FOR_SYNC; + } +} diff --git a/src/com/android/mail/providers/Folder.java b/src/com/android/mail/providers/Folder.java index 4b1e9045f..9b6fa5033 100644 --- a/src/com/android/mail/providers/Folder.java +++ b/src/com/android/mail/providers/Folder.java @@ -22,10 +22,12 @@ import android.database.Cursor; import android.graphics.PorterDuff; import android.graphics.drawable.Drawable; import android.graphics.drawable.PaintDrawable; +import android.graphics.drawable.StateListDrawable; import android.net.Uri; import android.os.Parcel; import android.os.Parcelable; import android.text.TextUtils; +import android.util.StateSet; import android.view.View; import android.widget.ImageView; @@ -637,6 +639,8 @@ public class Folder implements Parcelable, Comparable<Folder> { } } + private static final int[] ACTIVATED_STATE_LIST = new int[] {android.R.attr.state_activated}; + public static void setIcon(Folder folder, ImageView iconView) { if (iconView == null) { return; @@ -649,14 +653,31 @@ public class Folder implements Parcelable, Comparable<Folder> { } if (icon > 0) { - final Drawable iconDrawable = iconView.getResources().getDrawable(icon); - if (iconDrawable != null && - folder.supportsCapability(UIProvider.FolderCapabilities.TINT_ICON)) { - // Default multiply by white - iconDrawable.mutate().setColorFilter(folder.getBackgroundColor(0xFFFFFF), - PorterDuff.Mode.MULTIPLY); + final Drawable defaultIconDrawable = iconView.getResources().getDrawable(icon); + if (defaultIconDrawable != null) { + final Drawable iconDrawable; + if (folder.supportsCapability(UIProvider.FolderCapabilities.TINT_ICON)) { + // Default multiply by white + defaultIconDrawable.mutate().setColorFilter(folder.getBackgroundColor(0xFFFFFF), + PorterDuff.Mode.MULTIPLY); + iconDrawable = defaultIconDrawable; + } else { + final StateListDrawable listDrawable = new StateListDrawable(); + + final Drawable activatedIconDrawable = + iconView.getResources().getDrawable(icon); + activatedIconDrawable.mutate().setColorFilter(0xff000000, + PorterDuff.Mode.MULTIPLY); + + listDrawable.addState(ACTIVATED_STATE_LIST, activatedIconDrawable); + listDrawable.addState(StateSet.WILD_CARD, defaultIconDrawable); + + iconDrawable = listDrawable; + } + iconView.setImageDrawable(iconDrawable); + } else { + iconView.setImageDrawable(null); } - iconView.setImageDrawable(iconDrawable); } else { LogUtils.e(LogUtils.TAG, "No icon returned for folder %s", folder); } diff --git a/src/com/android/mail/ui/FolderListFragment.java b/src/com/android/mail/ui/FolderListFragment.java index 75bf21322..dbbc12b08 100644 --- a/src/com/android/mail/ui/FolderListFragment.java +++ b/src/com/android/mail/ui/FolderListFragment.java @@ -34,18 +34,18 @@ import android.widget.BaseAdapter; import android.widget.ImageView; import android.widget.ListAdapter; import android.widget.ListView; -import android.widget.TextView; import com.android.bitmap.BitmapCache; import com.android.bitmap.UnrefedBitmapCache; import com.android.mail.R; -import com.android.mail.adapter.DrawerItem; import com.android.mail.analytics.Analytics; import com.android.mail.bitmap.AccountAvatarDrawable; import com.android.mail.bitmap.ContactResolver; import com.android.mail.browse.MergedAdapter; import com.android.mail.content.ObjectCursor; import com.android.mail.content.ObjectCursorLoader; +import com.android.mail.drawer.DrawerItem; +import com.android.mail.drawer.FooterItem; import com.android.mail.providers.Account; import com.android.mail.providers.AccountObserver; import com.android.mail.providers.AllAccountObserver; @@ -185,7 +185,7 @@ public class FolderListFragment extends ListFragment implements * {@link DrawerItem#FOLDER_RECENT} or {@link DrawerItem#FOLDER_OTHER}. * Set as {@link DrawerItem#UNSET} to begin with, as there is nothing selected yet. */ - private int mSelectedDrawerItemType = DrawerItem.UNSET; + private int mSelectedDrawerItemCategory = DrawerItem.UNSET; /** The FolderType of the selected folder {@link FolderType} */ private int mSelectedFolderType = FolderType.INBOX; @@ -406,7 +406,7 @@ public class FolderListFragment extends ListFragment implements mListView.setChoiceMode(getListViewChoiceMode()); - mMergedAdapter = new MergedAdapter<ListAdapter>(); + mMergedAdapter = new MergedAdapter<>(); if (mAccountsAdapter != null) { mMergedAdapter.setAdapters(mAccountsAdapter, mFolderAdapter, mFooterAdapter); } else { @@ -465,7 +465,7 @@ public class FolderListFragment extends ListFragment implements if (savedState != null && savedState.containsKey(BUNDLE_SELECTED_FOLDER)) { mSelectedFolderUri = new FolderUri(Uri.parse(savedState.getString(BUNDLE_SELECTED_FOLDER))); - mSelectedDrawerItemType = savedState.getInt(BUNDLE_SELECTED_ITEM_TYPE); + mSelectedDrawerItemCategory = savedState.getInt(BUNDLE_SELECTED_ITEM_TYPE); mSelectedFolderType = savedState.getInt(BUNDLE_SELECTED_TYPE); } else if (mParentFolder != null) { mSelectedFolderUri = mParentFolder.folderUri; @@ -510,7 +510,7 @@ public class FolderListFragment extends ListFragment implements if (mSelectedFolderUri != null) { outState.putString(BUNDLE_SELECTED_FOLDER, mSelectedFolderUri.toString()); } - outState.putInt(BUNDLE_SELECTED_ITEM_TYPE, mSelectedDrawerItemType); + outState.putInt(BUNDLE_SELECTED_ITEM_TYPE, mSelectedDrawerItemCategory); outState.putInt(BUNDLE_SELECTED_TYPE, mSelectedFolderType); outState.putBoolean(BUNDLE_INBOX_PRESENT, mInboxPresent); } @@ -569,7 +569,7 @@ public class FolderListFragment extends ListFragment implements protected void changeAccount(final Account account) { // Switching accounts takes you to the default inbox for that account. - mSelectedDrawerItemType = DrawerItem.FOLDER_INBOX; + mSelectedDrawerItemCategory = DrawerItem.FOLDER_INBOX; mSelectedFolderType = FolderType.INBOX; mNextAccount = account; mAccountController.closeDrawer(true, mNextAccount, getDefaultInbox(mNextAccount)); @@ -585,12 +585,12 @@ public class FolderListFragment extends ListFragment implements final Object item = getListView().getAdapter().getItem(position); LogUtils.d(LOG_TAG, "viewFolderOrChangeAccount(%d): %s", position, item); final Folder folder; - int folderType = DrawerItem.UNSET; + @DrawerItem.DrawerItemCategory int itemCategory = DrawerItem.UNSET; if (item instanceof DrawerItem) { final DrawerItem drawerItem = (DrawerItem) item; - // Could be a folder or account. - final int itemType = drawerItem.mType; + // Could be a folder or account or footer + final @DrawerItem.DrawerItemType int itemType = drawerItem.getType(); if (itemType == DrawerItem.VIEW_ACCOUNT) { // Account, so switch. folder = null; @@ -598,10 +598,14 @@ public class FolderListFragment extends ListFragment implements } else if (itemType == DrawerItem.VIEW_FOLDER) { // Folder type, so change folders only. folder = drawerItem.mFolder; - mSelectedDrawerItemType = folderType = drawerItem.mFolderType; + mSelectedDrawerItemCategory = itemCategory = drawerItem.mItemCategory; mSelectedFolderType = folder.type; LogUtils.d(LOG_TAG, "FLF.viewFolderOrChangeAccount folder=%s, type=%d", - folder, mSelectedDrawerItemType); + folder, mSelectedDrawerItemCategory); + } else if (itemType == DrawerItem.VIEW_FOOTER_HELP || + itemType == DrawerItem.VIEW_FOOTER_SETTINGS) { + folder = null; + drawerItem.onClick(null /* unused */); } else { // Do nothing. LogUtils.d(LOG_TAG, "FolderListFragment: viewFolderOrChangeAccount():" @@ -610,16 +614,13 @@ public class FolderListFragment extends ListFragment implements } } else if (item instanceof Folder) { folder = (Folder) item; - } else if (item instanceof FooterItem) { - folder = null; - ((FooterItem) item).onClick(null /* unused */); } else { // Don't know how we got here. LogUtils.wtf(LOG_TAG, "viewFolderOrChangeAccount(): invalid item"); folder = null; } if (folder != null) { - final String label = (folderType == DrawerItem.FOLDER_RECENT) ? "recent" : "normal"; + final String label = (itemCategory == DrawerItem.FOLDER_RECENT) ? "recent" : "normal"; onFolderSelected(folder, label); } } @@ -677,7 +678,7 @@ public class FolderListFragment extends ListFragment implements LogUtils.wtf(LOG_TAG, "FLF.onCreateLoader() with weird type"); return null; } - return new ObjectCursorLoader<Folder>(mActivity.getActivityContext(), folderListUri, + return new ObjectCursorLoader<>(mActivity.getActivityContext(), folderListUri, UIProvider.FOLDERS_PROJECTION, Folder.FACTORY); } @@ -797,7 +798,7 @@ public class FolderListFragment extends ListFragment implements * {@link FolderListFragment#mIsDivided} for more information */ private final boolean mIsDivided; /** All the items */ - private List<DrawerItem> mItemList = new ArrayList<DrawerItem>(); + private List<DrawerItem> mItemList = new ArrayList<>(); /** Cursor into the folder list. This might be null. */ private ObjectCursor<Folder> mCursor = null; /** Cursor into the all folder list. This might be null. */ @@ -824,9 +825,9 @@ public class FolderListFragment extends ListFragment implements public View getView(int position, View convertView, ViewGroup parent) { final DrawerItem item = (DrawerItem) getItem(position); final View view = item.getView(convertView, parent); - final int type = item.mType; + final @DrawerItem.DrawerItemType int type = item.getType(); final boolean isSelected = - item.isHighlighted(mSelectedFolderUri, mSelectedDrawerItemType); + item.isHighlighted(mSelectedFolderUri, mSelectedDrawerItemCategory); if (type == DrawerItem.VIEW_FOLDER) { mListView.setItemChecked((mAccountsAdapter != null ? mAccountsAdapter.getCount() : 0) + @@ -847,12 +848,12 @@ public class FolderListFragment extends ListFragment implements @Override public int getViewTypeCount() { // Accounts, headers, folders (all parts of drawer view types) - return DrawerItem.getViewTypes(); + return DrawerItem.getViewTypeCount(); } @Override public int getItemViewType(int position) { - return ((DrawerItem) getItem(position)).mType; + return ((DrawerItem) getItem(position)).getType(); } @Override @@ -878,7 +879,7 @@ public class FolderListFragment extends ListFragment implements * @return a valid list of folders, which are all recent folders. */ private List<Folder> getRecentFolders(RecentFolderList recentList) { - final List<Folder> folderList = new ArrayList<Folder>(); + final List<Folder> folderList = new ArrayList<>(); if (recentList == null) { return folderList; } @@ -916,7 +917,7 @@ public class FolderListFragment extends ListFragment implements * This method modifies all the three lists on every single invocation. */ private List<DrawerItem> recalculateListFolders() { - final List<DrawerItem> itemList = new ArrayList<DrawerItem>(); + final List<DrawerItem> itemList = new ArrayList<>(); // If we are waiting for folder initialization, we don't have any kinds of folders, // just the "Waiting for initialization" item. Note, this should only be done // when we're waiting for account initialization or initial sync. @@ -938,8 +939,8 @@ public class FolderListFragment extends ListFragment implements // Recalculate folder list intended to be flat (no hearders or sections shown). // This is commonly used for the widget or other simple folder selections private List<DrawerItem> recalculateFlatListFolders(List<DrawerItem> itemList) { - final List<DrawerItem> inboxFolders = new ArrayList<DrawerItem>(); - final List<DrawerItem> allFoldersList = new ArrayList<DrawerItem>(); + final List<DrawerItem> inboxFolders = new ArrayList<>(); + final List<DrawerItem> allFoldersList = new ArrayList<>(); do { final Folder f = mCursor.getModel(); if (!isFolderTypeExcluded(f)) { @@ -961,8 +962,8 @@ public class FolderListFragment extends ListFragment implements // Recalculate folder list divided by sections (inboxes, recents, all, etc...) // This is primarily used by the drawer private List<DrawerItem> recalculateDividedListFolders(List<DrawerItem> itemList) { - final List<DrawerItem> allFoldersList = new ArrayList<DrawerItem>(); - final List<DrawerItem> inboxFolders = new ArrayList<DrawerItem>(); + final List<DrawerItem> allFoldersList = new ArrayList<>(); + final List<DrawerItem> inboxFolders = new ArrayList<>(); do { final Folder f = mCursor.getModel(); if (!isFolderTypeExcluded(f)) { @@ -1265,7 +1266,7 @@ public class FolderListFragment extends ListFragment implements */ private List<DrawerItem> buildAccountListDrawerItems() { final Account[] allAccounts = getAllAccounts(); - final List<DrawerItem> accountList = new ArrayList<DrawerItem>(allAccounts.length); + final List<DrawerItem> accountList = new ArrayList<>(allAccounts.length); // Add all accounts and then the current account final Uri currentAccountUri = getCurrentAccountUri(); for (final Account account : allAccounts) { @@ -1291,17 +1292,13 @@ public class FolderListFragment extends ListFragment implements return mMergedAdapter; } - public Account getCurrentAccount() { - return mCurrentAccount; - } - public ObjectCursor<Folder> getFoldersCursor() { return (mFolderAdapter != null) ? mFolderAdapter.getCursor() : null; } private class FooterAdapter extends BaseAdapter { - private final List<Object> mFooterItems = Lists.newArrayList(); + private final List<DrawerItem> mFooterItems = Lists.newArrayList(); private FooterAdapter() { update(); @@ -1313,7 +1310,7 @@ public class FolderListFragment extends ListFragment implements } @Override - public Object getItem(int position) { + public DrawerItem getItem(int position) { return mFooterItems.get(position); } @@ -1322,6 +1319,17 @@ public class FolderListFragment extends ListFragment implements return position; } + @Override + public int getViewTypeCount() { + // Accounts, headers, folders (all parts of drawer view types) + return DrawerItem.getViewTypeCount(); + } + + @Override + public int getItemViewType(int position) { + return getItem(position).getType(); + } + /** * @param convertView a view, possibly null, to be recycled. * @param parent the parent hosting this view. @@ -1329,35 +1337,7 @@ public class FolderListFragment extends ListFragment implements */ @Override public View getView(int position, View convertView, ViewGroup parent) { - final Object item = getItem(position); - if (item instanceof FooterItem) { - final ViewGroup footerItemView; - if (convertView != null) { - footerItemView = (ViewGroup) convertView; - } else { - footerItemView = (ViewGroup) getActivity().getLayoutInflater(). - inflate(R.layout.drawer_footer_item, parent, false); - } - - final FooterItem footerItem = (FooterItem) item; - - // adjust the text of the footer item - final TextView textView = (TextView) footerItemView. - findViewById(R.id.drawer_footer_text); - textView.setText(footerItem.getTextResourceID()); - - // adjust the icon of the footer item - final ImageView imageView = (ImageView) footerItemView. - findViewById(R.id.drawer_footer_image); - imageView.setImageResource(footerItem.getImageResourceID()); - return footerItemView; - } else if (item instanceof DrawerItem) { - final DrawerItem drawerItem = (DrawerItem) item; - return drawerItem.getView(convertView, parent); - } else { - throw new IllegalStateException("Only DrawerItems and FooterItems allowed, " + - item.toString()); - } + return getItem(position).getView(convertView, parent); } /** @@ -1374,11 +1354,13 @@ public class FolderListFragment extends ListFragment implements mFooterItems.clear(); if (mCurrentAccount != null) { - mFooterItems.add(new SettingsItem()); + mFooterItems.add(DrawerItem.ofSettingsItem(mActivity, mCurrentAccount, + mDrawerListener)); } if (mCurrentAccount != null && !Utils.isEmpty(mCurrentAccount.helpIntentUri)) { - mFooterItems.add(new HelpItem()); + mFooterItems.add(DrawerItem.ofHelpItem(mActivity, mCurrentAccount, + mDrawerListener)); } if (!mFooterItems.isEmpty()) { @@ -1412,9 +1394,9 @@ public class FolderListFragment extends ListFragment implements // any folder will take you to the default inbox for that account. (If you are in the // default inbox already, back exits the app.) // In both these cases, the selected folder type is not set, and must be set. - if (mSelectedDrawerItemType == DrawerItem.UNSET || (mCurrentAccount != null + if (mSelectedDrawerItemCategory == DrawerItem.UNSET || (mCurrentAccount != null && folder.folderUri.equals(mCurrentAccount.settings.defaultInbox))) { - mSelectedDrawerItemType = + mSelectedDrawerItemCategory = folder.isInbox() ? DrawerItem.FOLDER_INBOX : DrawerItem.FOLDER_OTHER; mSelectedFolderType = folder.type; } @@ -1496,91 +1478,11 @@ public class FolderListFragment extends ListFragment implements return mAccountController.getFolderListViewChoiceMode(); } - /** - * The base class of all footer items. Subclasses must fill in the logic of - * {@link #doFooterAction()} which contains the behavior when the item is selected. - */ - private abstract class FooterItem implements View.OnClickListener { - - private final int mImageResourceID; - private final int mTextResourceID; - - private FooterItem(final int imageResourceID, final int textResourceID) { - mImageResourceID = imageResourceID; - mTextResourceID = textResourceID; - } - - private int getImageResourceID() { - return mImageResourceID; - } - - private int getTextResourceID() { - return mTextResourceID; - } - - /** - * Executes the behavior associated with this footer item.<br> - * <br> - * WARNING: you probably don't want to call this directly; use - * {@link #onClick(View)} instead. This method actually performs the action, and its - * execution may be deferred from when the 'click' happens so we can smoothly close the - * drawer beforehand. - */ - abstract void doFooterAction(); - - @Override - public final void onClick(View v) { - final DrawerController dc = mActivity.getDrawerController(); - if (dc.isDrawerEnabled()) { - // close the drawer and defer handling the click until onDrawerClosed - mAccountController.closeDrawer(false /* hasNewFolderOrAccount */, - null /* nextAccount */, null /* nextFolder */); - mDrawerListener.setPendingFooterClick(this); - } else { - doFooterAction(); - } - } - - // for analytics - String getEventLabel() { - final StringBuilder sb = new StringBuilder("drawer_footer"); - sb.append("/"); - sb.append(mActivity.getViewMode().getModeString()); - return sb.toString(); - } - - } - - private class HelpItem extends FooterItem { - protected HelpItem() { - super(R.drawable.ic_drawer_help_24dp, R.string.help_and_feedback); - } - - @Override - void doFooterAction() { - Analytics.getInstance().sendMenuItemEvent(Analytics.EVENT_CATEGORY_MENU_ITEM, - R.id.help_info_menu_item, getEventLabel(), 0); - mActivity.showHelp(mCurrentAccount, ViewMode.CONVERSATION_LIST); - } - } - - private class SettingsItem extends FooterItem { - protected SettingsItem() { - super(R.drawable.ic_drawer_settings_24dp, R.string.menu_settings); - } - - @Override - void doFooterAction() { - Analytics.getInstance().sendMenuItemEvent(Analytics.EVENT_CATEGORY_MENU_ITEM, - R.id.settings, getEventLabel(), 0); - Utils.showSettings(mActivity.getActivityContext(), mCurrentAccount); - } - } /** * Drawer listener for footer functionality to react to drawer state. */ - private class DrawerStateListener implements DrawerLayout.DrawerListener { + public class DrawerStateListener implements DrawerLayout.DrawerListener { private FooterItem mPendingFooterClick; @@ -1597,7 +1499,7 @@ public class FolderListFragment extends ListFragment implements @Override public void onDrawerClosed(View drawerView) { if (mPendingFooterClick != null) { - mPendingFooterClick.doFooterAction(); + mPendingFooterClick.onFooterClicked(); mPendingFooterClick = null; } } |