Use MergedAdapter in FolderListFragment.
Instead of using one adapter that contained the accounts
and the folders, the adapter now contains two sub-adapters,
and AccountsAdapter and a FolderAdapter. Functionality
should be unchanged.
Change-Id: I18c945cdcf9519549ab3c2886be033b398af086c
diff --git a/src/com/android/mail/adapter/DrawerItem.java b/src/com/android/mail/adapter/DrawerItem.java
index 093bdd3..b74cba0 100644
--- a/src/com/android/mail/adapter/DrawerItem.java
+++ b/src/com/android/mail/adapter/DrawerItem.java
@@ -50,9 +50,9 @@
private static final String LOG_TAG = LogTag.getLogTag();
public final Folder mFolder;
public final Account mAccount;
- public final int mResource;
+ private final int mResource;
/** True if the drawer item represents the current account, false otherwise */
- public boolean mIsSelected;
+ 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. */
diff --git a/src/com/android/mail/browse/MergedAdapter.java b/src/com/android/mail/browse/MergedAdapter.java
index 0212095..9689dca 100644
--- a/src/com/android/mail/browse/MergedAdapter.java
+++ b/src/com/android/mail/browse/MergedAdapter.java
@@ -22,7 +22,6 @@
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ListAdapter;
-import android.widget.SpinnerAdapter;
import java.util.Arrays;
import java.util.List;
@@ -32,26 +31,27 @@
*
* @param <T> the class of each constituent adapter
*/
-public class MergedAdapter<T extends MergedAdapter.ListSpinnerAdapter> extends BaseAdapter {
+public class MergedAdapter<T extends ListAdapter> extends BaseAdapter {
private List<T> mAdapters;
private final DataSetObserver mObserver;
- /**
- * A Mergeable adapter must implement both ListAdapter and SpinnerAdapter to be useful in lists
- * and spinners.
- */
- public interface ListSpinnerAdapter extends ListAdapter, SpinnerAdapter {
- }
-
- public static class LocalAdapterPosition<T extends ListSpinnerAdapter> {
- public final T mAdapter;
- public final int mLocalPosition;
+ public static class LocalAdapterPosition<T extends ListAdapter> {
+ private final T mAdapter;
+ private final int mLocalPosition;
public LocalAdapterPosition(T adapter, int offset) {
mAdapter = adapter;
mLocalPosition = offset;
}
+
+ public T getAdapter() {
+ return mAdapter;
+ }
+
+ public int getLocalPosition() {
+ return mLocalPosition;
+ }
}
public MergedAdapter() {
@@ -169,12 +169,6 @@
}
@Override
- public View getDropDownView(int position, View convertView, ViewGroup parent) {
- LocalAdapterPosition<T> result = getAdapterOffsetForItem(position);
- return result.mAdapter.getDropDownView(result.mLocalPosition, convertView, parent);
- }
-
- @Override
public boolean areAllItemsEnabled() {
boolean enabled = true;
for (T adapter : mAdapters) {
diff --git a/src/com/android/mail/browse/MultiAdapterSpinner.java b/src/com/android/mail/browse/MultiAdapterSpinner.java
deleted file mode 100644
index 07c9db5..0000000
--- a/src/com/android/mail/browse/MultiAdapterSpinner.java
+++ /dev/null
@@ -1,185 +0,0 @@
-/*
- * Copyright (C) 2012 Google Inc.
- * Licensed to 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.browse;
-
-import com.android.mail.browse.MergedAdapter.ListSpinnerAdapter;
-import com.android.mail.browse.MergedAdapter.LocalAdapterPosition;
-
-import android.content.Context;
-import android.graphics.Rect;
-import android.graphics.drawable.Drawable;
-import android.util.AttributeSet;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.AdapterView;
-import android.widget.FrameLayout;
-import android.widget.ListPopupWindow;
-import android.widget.ListView;
-
-
-/**
- * <p>A spinner-like widget that combines data and views from multiple adapters (via MergedAdapter)
- * and forwards certain events to those adapters. This widget also supports clickable but
- * unselectable dropdown items, useful when displaying extra items that should not affect spinner
- * selection state.</p>
- *
- * <p>The framework's Spinner widget can't be extended for this task because it uses a private list
- * adapter (which prevents setting multiple item types) and hides access to its popup, which is
- * useful for clients to know about (like when it's been opened).</p>
- *
- * <p>Clients must provide a set of adapters which the widget will use to load dropdown views,
- * receive callbacks, and load the selected item's view.</p>
- *
- * <p>Apps incorporating this widget must declare a custom attribute: "dropDownWidth" under the
- * "MultiAdapterSpinner" name as a "reference" format (see Gmail's attrs.xml file for an
- * example). This attribute controls the width of the dropdown, similar to the attribute in the
- * framework's Spinner widget.</p>
- *
- */
-public class MultiAdapterSpinner extends FrameLayout
- implements AdapterView.OnItemClickListener, View.OnClickListener {
-
- protected MergedAdapter<FancySpinnerAdapter> mAdapter;
- protected ListPopupWindow mPopup;
-
- private int mSelectedPosition = -1;
- private Rect mTempRect = new Rect();
-
- /**
- * A basic adapter with some callbacks added so clients can be involved in spinner behavior.
- */
- public interface FancySpinnerAdapter extends ListSpinnerAdapter {
- /**
- * Whether or not an item at position should become the new selected spinner item and change
- * the spinner item view.
- */
- boolean canSelect(int position);
- /**
- * Handle a click on an enabled item.
- */
- void onClick(int position);
- /**
- * Fired when the popup window is about to be displayed.
- */
- void onShowPopup();
- }
-
- private static class MergedSpinnerAdapter extends MergedAdapter<FancySpinnerAdapter> {
- /**
- * ListPopupWindow uses getView() but spinners return dropdown views in getDropDownView().
- */
- @Override
- public View getView(int position, View convertView, ViewGroup parent) {
- return super.getDropDownView(position, convertView, parent);
- }
- }
-
- public MultiAdapterSpinner(Context context) {
- this(context, null);
- }
-
- public MultiAdapterSpinner(Context context, AttributeSet attrs) {
- super(context, attrs);
-
- mAdapter = new MergedSpinnerAdapter();
- mPopup = new ListPopupWindow(context, attrs);
- mPopup.setAnchorView(this);
- mPopup.setOnItemClickListener(this);
- mPopup.setModal(true);
- mPopup.setAdapter(mAdapter);
- }
-
- public void setAdapters(FancySpinnerAdapter... adapters) {
- mAdapter.setAdapters(adapters);
- }
-
- public void setSelectedItem(final FancySpinnerAdapter adapter, final int position) {
- int globalPosition = 0;
- boolean found = false;
-
- for (int i = 0, count = mAdapter.getSubAdapterCount(); i < count; i++) {
- ListSpinnerAdapter a = mAdapter.getSubAdapter(i);
- if (a == adapter) {
- globalPosition += position;
- found = true;
- break;
- }
- globalPosition += a.getCount();
- }
- if (found) {
- if (adapter.canSelect(position)) {
- removeAllViews();
- View itemView = adapter.getView(position, null, this);
- itemView.setClickable(true);
- itemView.setOnClickListener(this);
- addView(itemView);
-
- if (position < adapter.getCount()) {
- mSelectedPosition = globalPosition;
- }
- }
- }
- }
-
- @Override
- public void onClick(View v) {
- if (!mPopup.isShowing()) {
-
- for (int i = 0, count = mAdapter.getSubAdapterCount(); i < count; i++) {
- mAdapter.getSubAdapter(i).onShowPopup();
- }
-
- final int spinnerPaddingLeft = getPaddingLeft();
- final Drawable background = mPopup.getBackground();
- int bgOffset = 0;
- if (background != null) {
- background.getPadding(mTempRect);
- bgOffset = -mTempRect.left;
- }
- mPopup.setHorizontalOffset(bgOffset + spinnerPaddingLeft);
- mPopup.show();
- mPopup.getListView().setChoiceMode(ListView.CHOICE_MODE_SINGLE);
- mPopup.setSelection(mSelectedPosition);
- }
- }
-
- @Override
- public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
-
- if (position != mSelectedPosition) {
- final LocalAdapterPosition<FancySpinnerAdapter> result =
- mAdapter.getAdapterOffsetForItem(position);
-
- if (result.mAdapter.canSelect(result.mLocalPosition)) {
- mSelectedPosition = position;
- } else {
- mPopup.clearListSelection();
- }
-
- post(new Runnable() {
- @Override
- public void run() {
- result.mAdapter.onClick(result.mLocalPosition);
- }
- });
- }
-
- mPopup.dismiss();
- }
-
-}
diff --git a/src/com/android/mail/ui/AbstractActivityController.java b/src/com/android/mail/ui/AbstractActivityController.java
index 20528ec..28b696d 100644
--- a/src/com/android/mail/ui/AbstractActivityController.java
+++ b/src/com/android/mail/ui/AbstractActivityController.java
@@ -4185,10 +4185,6 @@
mHideMenuItems = true;
mActivity.invalidateOptionsMenu();
disableCabMode();
- final FolderListFragment folderListFragment = getFolderListFragment();
- if (folderListFragment != null) {
- folderListFragment.updateScroll();
- }
}
} else {
if (mHideMenuItems && Float.compare(slideOffset, 0.f) == 0) {
@@ -4199,10 +4195,6 @@
mHideMenuItems = true;
mActivity.invalidateOptionsMenu();
disableCabMode();
- final FolderListFragment folderListFragment = getFolderListFragment();
- if (folderListFragment != null) {
- folderListFragment.updateScroll();
- }
}
}
diff --git a/src/com/android/mail/ui/FolderListFragment.java b/src/com/android/mail/ui/FolderListFragment.java
index f3ed68c..74c00ec 100644
--- a/src/com/android/mail/ui/FolderListFragment.java
+++ b/src/com/android/mail/ui/FolderListFragment.java
@@ -36,6 +36,7 @@
import com.android.mail.R;
import com.android.mail.adapter.DrawerItem;
import com.android.mail.analytics.Analytics;
+import com.android.mail.browse.MergedAdapter;
import com.android.mail.content.ObjectCursor;
import com.android.mail.content.ObjectCursorLoader;
import com.android.mail.providers.Account;
@@ -136,7 +137,12 @@
private static final String BUNDLE_SELECTED_FOLDER = "flf-selected-folder";
private static final String BUNDLE_SELECTED_TYPE = "flf-selected-type";
- private FolderListFragmentCursorAdapter mCursorAdapter;
+ /** Adapter used by the list that wraps both the folder adapter and the accounts adapter. */
+ private MergedAdapter<ListAdapter> mMergedAdapter;
+ /** Adapter containing the list of accounts. */
+ private AccountsAdapter mAccountsAdapter;
+ /** Adapter containing the list of folders and, optionally, headers and the wait view. */
+ private FolderListFragmentCursorAdapter mFolderAdapter;
/** Observer to wait for changes to the current folder so we can change the selected folder */
private FolderObserver mFolderObserver = null;
/** Listen for account changes. */
@@ -157,6 +163,9 @@
private Account mNextAccount = null;
/** The folder we will change to once the drawer (if any) is closed */
private Folder mNextFolder = null;
+ /** Watcher for tracking and receiving unread counts for mail */
+ private FolderWatcher mFolderWatcher = null;
+ private boolean mRegistered = false;
/**
* Constructor needs to be public to handle orientation changes and activity lifecycle events.
@@ -174,7 +183,7 @@
sb.append(" parent=");
sb.append(mParentFolder);
sb.append(" adapterCount=");
- sb.append(mCursorAdapter != null ? mCursorAdapter.getCount() : -1);
+ sb.append(mMergedAdapter != null ? mMergedAdapter.getCount() : -1);
sb.append("}");
return sb.toString();
}
@@ -266,12 +275,15 @@
// mActivity being initialized.
final Folder selectedFolder;
if (mParentFolder != null) {
- mCursorAdapter = new HierarchicalFolderListAdapter(null, mParentFolder);
+ mFolderAdapter = new HierarchicalFolderListAdapter(null, mParentFolder);
selectedFolder = mActivity.getHierarchyFolder();
} else {
- mCursorAdapter = new FolderListAdapter(mIsDivided);
+ mFolderAdapter = new FolderAdapter(mIsDivided);
selectedFolder = currentFolder;
}
+
+ mAccountsAdapter = new AccountsAdapter();
+
// Is the selected folder fresher than the one we have restored from a bundle?
if (selectedFolder != null
&& !selectedFolder.folderUri.equals(mSelectedFolderUri)) {
@@ -294,7 +306,13 @@
mAllAccountsObserver = new AllAccountObserver(){
@Override
public void onChanged(Account[] allAccounts) {
- mCursorAdapter.notifyAllAccountsChanged();
+ if (!mRegistered && mAccountController != null) {
+ // TODO(viki): Round-about way of setting the watcher. http://b/8750610
+ mAccountController.setFolderWatcher(mFolderWatcher);
+ mRegistered = true;
+ }
+ mFolderWatcher.updateAccountList(getAllAccounts());
+ mAccountsAdapter.rebuildAccountList();
}
};
mAllAccountsObserver.initialize(accountController);
@@ -326,7 +344,13 @@
mListView.setChoiceMode(getListViewChoiceMode());
- setListAdapter(mCursorAdapter);
+ mMergedAdapter = new MergedAdapter<ListAdapter>();
+ mMergedAdapter.setAdapters(mAccountsAdapter, mFolderAdapter);
+
+ mFolderWatcher = new FolderWatcher(mActivity, mAccountsAdapter);
+ mFolderWatcher.updateAccountList(getAllAccounts());
+
+ setListAdapter(mMergedAdapter);
}
/**
@@ -398,8 +422,8 @@
@Override
public void onDestroyView() {
- if (mCursorAdapter != null) {
- mCursorAdapter.destroy();
+ if (mFolderAdapter != null) {
+ mFolderAdapter.destroy();
}
// Clear the adapter.
setListAdapter(null);
@@ -428,10 +452,10 @@
}
private Folder getDefaultInbox(Account account) {
- if (account == null || mCursorAdapter == null) {
+ if (account == null || mFolderWatcher == null) {
return null;
}
- return mCursorAdapter.getDefaultInbox(account);
+ return mFolderWatcher.getDefaultInbox(account);
}
private void changeAccount(final Account account) {
@@ -455,7 +479,7 @@
if (item instanceof DrawerItem) {
final DrawerItem drawerItem = (DrawerItem) item;
// Could be a folder or account.
- final int itemType = mCursorAdapter.getItemType(drawerItem);
+ final int itemType = drawerItem.mType;
if (itemType == DrawerItem.VIEW_ACCOUNT) {
// Account, so switch.
folder = null;
@@ -535,22 +559,22 @@
@Override
public void onLoadFinished(Loader<ObjectCursor<Folder>> loader, ObjectCursor<Folder> data) {
- if (mCursorAdapter != null) {
+ if (mFolderAdapter != null) {
if (loader.getId() == FOLDER_LIST_LOADER_ID) {
- mCursorAdapter.setCursor(data);
+ mFolderAdapter.setCursor(data);
} else if (loader.getId() == ALL_FOLDER_LIST_LOADER_ID) {
- mCursorAdapter.setAllFolderListCursor(data);
+ mFolderAdapter.setAllFolderListCursor(data);
}
}
}
@Override
public void onLoaderReset(Loader<ObjectCursor<Folder>> loader) {
- if (mCursorAdapter != null) {
+ if (mFolderAdapter != null) {
if (loader.getId() == FOLDER_LIST_LOADER_ID) {
- mCursorAdapter.setCursor(null);
+ mFolderAdapter.setCursor(null);
} else if (loader.getId() == ALL_FOLDER_LIST_LOADER_ID) {
- mCursorAdapter.setAllFolderListCursor(null);
+ mFolderAdapter.setAllFolderListCursor(null);
}
}
}
@@ -575,34 +599,22 @@
void setCursor(ObjectCursor<Folder> cursor);
/** Update the all folder list cursor with the cursor given here. */
void setAllFolderListCursor(ObjectCursor<Folder> cursor);
- /**
- * Given an item, find the type of the item, which should only be {@link
- * DrawerItem#VIEW_FOLDER} or {@link DrawerItem#VIEW_ACCOUNT}
- * @return item the type of the item.
- */
- int getItemType(DrawerItem item);
- /** Notify that the all accounts changed. */
- void notifyAllAccountsChanged();
/** Remove all observers and destroy the object. */
void destroy();
/** Notifies the adapter that the data has changed. */
void notifyDataSetChanged();
- /** Returns default inbox for this account. */
- Folder getDefaultInbox(Account account);
- /** Returns the index of the first selected item, or -1 if no selection */
- int getSelectedPosition();
}
/**
* An adapter for flat folder lists.
*/
- private class FolderListAdapter extends BaseAdapter implements FolderListFragmentCursorAdapter {
+ private class FolderAdapter extends BaseAdapter implements FolderListFragmentCursorAdapter {
private final RecentFolderObserver mRecentFolderObserver = new RecentFolderObserver() {
@Override
public void onChanged() {
if (!isCursorInvalid()) {
- recalculateList();
+ rebuildFolderList();
}
}
};
@@ -619,17 +631,14 @@
private ObjectCursor<Folder> mCursor = null;
/** Cursor into the all folder list. This might be null. */
private ObjectCursor<Folder> mAllFolderListCursor = null;
- /** Watcher for tracking and receiving unread counts for mail */
- private FolderWatcher mFolderWatcher = null;
- private boolean mRegistered = false;
/**
- * Creates a {@link FolderListAdapter}.This is a list of all the accounts and folders.
+ * Creates a {@link FolderAdapter}. This is a list of all the accounts and folders.
*
* @param isDivided true if folder list is flat, false if divided by label group. See
* the comments on {@link #mIsDivided} for more information
*/
- public FolderListAdapter(boolean isDivided) {
+ public FolderAdapter(boolean isDivided) {
super();
mIsDivided = isDivided;
final RecentFolderController controller = mActivity.getRecentFolderController();
@@ -638,19 +647,6 @@
} else {
mRecentFolders = null;
}
- mFolderWatcher = new FolderWatcher(mActivity, this);
- mFolderWatcher.updateAccountList(getAllAccounts());
- }
-
- @Override
- public void notifyAllAccountsChanged() {
- if (!mRegistered && mAccountController != null) {
- // TODO(viki): Round-about way of setting the watcher. http://b/8750610
- mAccountController.setFolderWatcher(mFolderWatcher);
- mRegistered = true;
- }
- mFolderWatcher.updateAccountList(getAllAccounts());
- recalculateList();
}
@Override
@@ -660,7 +656,7 @@
final int type = item.mType;
final boolean isSelected = item.isHighlighted(mSelectedFolderUri, mSelectedFolderType);
if (type == DrawerItem.VIEW_FOLDER) {
- mListView.setItemChecked(position, isSelected);
+ mListView.setItemChecked(mAccountsAdapter.getCount() + position, isSelected);
}
// If this is the current folder, also check to verify that the unread count
// matches what the action bar shows.
@@ -696,10 +692,6 @@
return drawerItem != null && drawerItem.isItemEnabled();
}
- private Uri getCurrentAccountUri() {
- return mCurrentAccount == null ? Uri.EMPTY : mCurrentAccount.uri;
- }
-
@Override
public boolean areAllItemsEnabled() {
// We have headers and thus some items are not enabled.
@@ -728,46 +720,20 @@
/**
* Responsible for verifying mCursor, and ensuring any recalculate
* conditions are met. Also calls notifyDataSetChanged once it's finished
- * populating {@link FolderListAdapter#mItemList}
+ * populating {@link com.android.mail.ui.FolderListFragment.FolderAdapter#mItemList}
*/
- private void recalculateList() {
- final List<DrawerItem> newFolderList = new ArrayList<DrawerItem>();
- // Don't show accounts for single-account-based folder selection (i.e. widgets)
- if (!mHideAccounts) {
- recalculateListAccounts(newFolderList);
- }
- recalculateListFolders(newFolderList);
- mItemList = newFolderList;
+ private void rebuildFolderList() {
+ mItemList = recalculateListFolders();
// Ask the list to invalidate its views.
notifyDataSetChanged();
}
/**
- * Recalculates the accounts if not null and adds them to the list.
- *
- * @param itemList List of drawer items to populate
- */
- private void recalculateListAccounts(List<DrawerItem> itemList) {
- final Account[] allAccounts = getAllAccounts();
- // Add all accounts and then the current account
- final Uri currentAccountUri = getCurrentAccountUri();
- for (final Account account : allAccounts) {
- final int unreadCount = mFolderWatcher.getUnreadCount(account);
- itemList.add(DrawerItem.ofAccount(mActivity, account, unreadCount,
- currentAccountUri.equals(account.uri), mBidiFormatter));
- }
- if (mCurrentAccount == null) {
- LogUtils.wtf(LOG_TAG, "recalculateListAccounts() with null current account.");
- }
- }
-
- /**
* Recalculates the system, recent and user label lists.
* This method modifies all the three lists on every single invocation.
- *
- * @param itemList List of drawer items to populate
*/
- private void recalculateListFolders(List<DrawerItem> itemList) {
+ private List<DrawerItem> recalculateListFolders() {
+ final List<DrawerItem> itemList = new ArrayList<DrawerItem>();
// 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.
@@ -775,7 +741,7 @@
if(!mCurrentAccount.isAccountReady()) {
itemList.add(DrawerItem.ofWaitView(mActivity, mBidiFormatter));
}
- return;
+ return itemList;
}
if (!mIsDivided) {
@@ -788,7 +754,7 @@
}
} while (mCursor.moveToNext());
- return;
+ return itemList;
}
// Otherwise, this is an adapter for a divided list.
@@ -843,6 +809,8 @@
// Add the remaining folders.
addFolderDivision(itemList, allFoldersList, R.string.all_folders_heading);
+
+ return itemList;
}
/**
@@ -852,7 +820,7 @@
* @param destination List of drawer items to populate
* @param source List of drawer items representing folders to add to the drawer
* @param headerStringResource
- * {@link FolderListAdapter#NO_HEADER_RESOURCE} if no header
+ * {@link FolderAdapter#NO_HEADER_RESOURCE} if no header
* is required, or res-id otherwise. The integer is interpreted as the string
* for the header's title.
*/
@@ -909,13 +877,15 @@
@Override
public void setCursor(ObjectCursor<Folder> cursor) {
mCursor = cursor;
- recalculateList();
+ mAccountsAdapter.rebuildAccountList();
+ rebuildFolderList();
}
@Override
public void setAllFolderListCursor(final ObjectCursor<Folder> cursor) {
mAllFolderListCursor = cursor;
- recalculateList();
+ mAccountsAdapter.rebuildAccountList();
+ rebuildFolderList();
}
@Override
@@ -937,33 +907,6 @@
public final void destroy() {
mRecentFolderObserver.unregisterAndDestroy();
}
-
- @Override
- public Folder getDefaultInbox(Account account) {
- if (mFolderWatcher != null) {
- return mFolderWatcher.getDefaultInbox(account);
- }
- return null;
- }
-
- @Override
- public int getItemType(DrawerItem item) {
- return item.mType;
- }
-
- @Override
- public int getSelectedPosition() {
- for (int i = 0; i < mItemList.size(); i++) {
- final DrawerItem item = (DrawerItem) getItem(i);
- final boolean isSelected =
- item.isHighlighted(mSelectedFolderUri, mSelectedFolderType);
- if (isSelected) {
- return i;
- }
- }
-
- return -1;
- }
}
private class HierarchicalFolderListAdapter extends ArrayAdapter<Folder>
@@ -1009,7 +952,7 @@
}
folderItemView.bind(folder, mDropHandler, mBidiFormatter);
if (folder.folderUri.equals(mSelectedFolderUri)) {
- getListView().setItemChecked(position, true);
+ getListView().setItemChecked(mAccountsAdapter.getCount() + position, true);
// If this is the current folder, also check to verify that the unread count
// matches what the action bar shows.
final boolean unreadCountDiffers = (mCurrentFolderForUnreadCheck != null)
@@ -1046,34 +989,70 @@
public void destroy() {
// Do nothing.
}
+ }
- @Override
- public Folder getDefaultInbox(Account account) {
- return null;
+ private class AccountsAdapter extends BaseAdapter {
+
+ private List<DrawerItem> mAccounts;
+
+ public AccountsAdapter() {
+ mAccounts = new ArrayList<DrawerItem>();
}
- @Override
- public int getItemType(DrawerItem item) {
- // Always returns folders for now.
- return DrawerItem.VIEW_FOLDER;
- }
-
- @Override
- public void notifyAllAccountsChanged() {
- // Do nothing. We don't care about changes to all accounts.
- }
-
- @Override
- public int getSelectedPosition() {
- final int count = getCount();
- for (int i = 0; i < count; i++) {
- final Folder folder = getItem(i);
- final boolean isSelected = folder.folderUri.equals(mSelectedFolderUri);
- if (isSelected) {
- return i;
- }
+ public void rebuildAccountList() {
+ if (!mHideAccounts) {
+ mAccounts = buildAccountList();
+ notifyDataSetChanged();
}
- return -1;
+ }
+
+ /**
+ * Builds the accounts adapter.
+ */
+ private List<DrawerItem> buildAccountList() {
+ final List<DrawerItem> accountList = new ArrayList<DrawerItem>();
+ final Account[] allAccounts = getAllAccounts();
+ // Add all accounts and then the current account
+ final Uri currentAccountUri = getCurrentAccountUri();
+ for (final Account account : allAccounts) {
+ final int unreadCount = mFolderWatcher.getUnreadCount(account);
+ accountList.add(DrawerItem.ofAccount(mActivity, account, unreadCount,
+ currentAccountUri.equals(account.uri), mBidiFormatter));
+ }
+ if (mCurrentAccount == null) {
+ LogUtils.wtf(LOG_TAG, "buildAccountList() with null current account.");
+ }
+ return accountList;
+ }
+
+ private Uri getCurrentAccountUri() {
+ return mCurrentAccount == null ? Uri.EMPTY : mCurrentAccount.uri;
+ }
+
+ @Override
+ public int getCount() {
+ return mAccounts.size();
+ }
+
+ @Override
+ public Object getItem(int position) {
+ // Is there an attempt made to access outside of the drawer item list?
+ if (position >= mAccounts.size()) {
+ return null;
+ } else {
+ return mAccounts.get(position);
+ }
+ }
+
+ @Override
+ public long getItemId(int position) {
+ return getItem(position).hashCode();
+ }
+
+ @Override
+ public View getView(int position, View convertView, ViewGroup parent) {
+ final DrawerItem item = (DrawerItem) getItem(position);
+ return item.getView(convertView, parent);
}
}
@@ -1107,18 +1086,8 @@
mCurrentFolderForUnreadCheck = folder;
mSelectedFolderUri = folder.folderUri;
- if (mCursorAdapter != null && viewChanged) {
- mCursorAdapter.notifyDataSetChanged();
- }
- }
-
- public void updateScroll() {
- final int selectedPosition = mCursorAdapter.getSelectedPosition();
- if (selectedPosition >= 0) {
- // TODO: setSelection() jumps the item to the top of the list "hiding" the accounts
- // TODO: and smoothScrollToPosition() is too slow for lots of labels/folders
- // It's called "setSelection" but it's really more like "jumpScrollToPosition"
- // mListView.setSelection(selectedPosition);
+ if (mFolderAdapter != null && viewChanged) {
+ mFolderAdapter.notifyDataSetChanged();
}
}
@@ -1132,7 +1101,7 @@
mCurrentAccount = account;
if (changed) {
// We no longer have proper folder objects. Let the new ones come in
- mCursorAdapter.setCursor(null);
+ mFolderAdapter.setCursor(null);
// If currentAccount is different from the one we set, restart the loader. Look at the
// comment on {@link AbstractActivityController#restartOptionalLoader} to see why we
// don't just do restartLoader.