Clean up MailboxListFragment.
- Remove AsyncTasks, and use CursorLoader to load data. - Get message counts for the drafts/trash mailboxes directly from the db column. - Remove obsolete code from MailboxesAdapter. Change-Id: I93c72977c19b60581e1169ba9bd429912ba3e68f
This commit is contained in:
parent
d0c2178063
commit
7ef278202e
|
@ -45,12 +45,6 @@
|
|||
android:layout_height="wrap_content"
|
||||
android:textAppearance="?android:attr/textAppearanceMedium"
|
||||
android:textColor="?android:attr/textColorPrimary" />
|
||||
<TextView
|
||||
android:id="@+id/mailbox_status"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textAppearance="?android:attr/textAppearanceSmall"
|
||||
android:textColor="?android:attr/textColorTertiary" />
|
||||
</LinearLayout>
|
||||
<TextView
|
||||
android:id="@+id/new_message_count"
|
||||
|
|
|
@ -17,23 +17,15 @@
|
|||
package com.android.email.activity;
|
||||
|
||||
import com.android.email.Email;
|
||||
import com.android.email.R;
|
||||
import com.android.email.Utility;
|
||||
import com.android.email.provider.EmailContent;
|
||||
import com.android.email.provider.EmailContent.Mailbox;
|
||||
import com.android.email.provider.EmailContent.MailboxColumns;
|
||||
import com.android.email.provider.EmailContent.Message;
|
||||
import com.android.email.provider.EmailContent.MessageColumns;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.ListFragment;
|
||||
import android.app.LoaderManager.LoaderCallbacks;
|
||||
import android.content.Loader;
|
||||
import android.database.Cursor;
|
||||
import android.os.AsyncTask;
|
||||
import android.os.Bundle;
|
||||
import android.os.Parcelable;
|
||||
import android.util.Log;
|
||||
import android.view.ContextMenu;
|
||||
import android.view.ContextMenu.ContextMenuInfo;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.widget.AdapterView;
|
||||
import android.widget.AdapterView.OnItemClickListener;
|
||||
|
@ -50,23 +42,14 @@ import java.security.InvalidParameterException;
|
|||
* - pass-through implementations of onCreateContextMenu() and onContextItemSelected() (temporary)
|
||||
*/
|
||||
public class MailboxListFragment extends ListFragment implements OnItemClickListener {
|
||||
|
||||
private static final String MAILBOX_SELECTION = MailboxColumns.ACCOUNT_KEY + "=?" +
|
||||
" AND " + MailboxColumns.TYPE + "<" + Mailbox.TYPE_NOT_EMAIL +
|
||||
" AND " + MailboxColumns.FLAG_VISIBLE + "=1";
|
||||
private static final String MESSAGE_MAILBOX_ID_SELECTION = MessageColumns.MAILBOX_KEY + "=?";
|
||||
|
||||
// Account & mailboxes access
|
||||
private static final int LOADER_ID_MAILBOX_LIST = 1;
|
||||
private long mAccountId = -1;
|
||||
private LoadMailboxesTask mLoadMailboxesTask;
|
||||
private MessageCountTask mMessageCountTask;
|
||||
private long mDraftMailboxKey = -1;
|
||||
private long mTrashMailboxKey = -1;
|
||||
|
||||
// UI Support
|
||||
private Activity mActivity;
|
||||
private MailboxesAdapter mListAdapter;
|
||||
private Callback mCallback = EmptyCallback.INSTANCE;
|
||||
private final MyLoaderCallbacks mMyLoaderCallbacks = new MyLoaderCallbacks();
|
||||
|
||||
private boolean mStarted;
|
||||
|
||||
|
@ -150,6 +133,7 @@ public class MailboxListFragment extends ListFragment implements OnItemClickList
|
|||
if (Email.DEBUG_LIFECYCLE && Email.DEBUG) {
|
||||
Log.d(Email.LOG_TAG, "MailboxListFragment onStart");
|
||||
}
|
||||
getLoaderManager(); // TODO Work around internal bug 2887723.
|
||||
super.onStart();
|
||||
mStarted = true;
|
||||
if (mAccountId != -1) {
|
||||
|
@ -166,7 +150,6 @@ public class MailboxListFragment extends ListFragment implements OnItemClickList
|
|||
Log.d(Email.LOG_TAG, "MailboxListFragment onResume");
|
||||
}
|
||||
super.onResume();
|
||||
updateMessageCount();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -187,7 +170,6 @@ public class MailboxListFragment extends ListFragment implements OnItemClickList
|
|||
}
|
||||
mStarted = false;
|
||||
super.onStop();
|
||||
cancelAllTasks();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -199,8 +181,6 @@ public class MailboxListFragment extends ListFragment implements OnItemClickList
|
|||
Log.d(Email.LOG_TAG, "MailboxListFragment onDestroy");
|
||||
}
|
||||
super.onDestroy();
|
||||
|
||||
mListAdapter.changeCursor(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -211,166 +191,41 @@ public class MailboxListFragment extends ListFragment implements OnItemClickList
|
|||
super.onSaveInstanceState(outState);
|
||||
}
|
||||
|
||||
private void cancelAllTasks() {
|
||||
Utility.cancelTaskInterrupt(mLoadMailboxesTask);
|
||||
mLoadMailboxesTask = null;
|
||||
Utility.cancelTaskInterrupt(mMessageCountTask);
|
||||
mMessageCountTask = null;
|
||||
}
|
||||
|
||||
private void startLoading() {
|
||||
cancelAllTasks();
|
||||
|
||||
if (Email.DEBUG_LIFECYCLE && Email.DEBUG) {
|
||||
Log.d(Email.LOG_TAG, "MailboxListFragment startLoading");
|
||||
}
|
||||
// Clear the list. (ListFragment will show the "Loading" animation)
|
||||
setListAdapter(null);
|
||||
setListShown(false);
|
||||
|
||||
mLoadMailboxesTask = new LoadMailboxesTask(mAccountId);
|
||||
mLoadMailboxesTask.execute();
|
||||
getLoaderManager().restartLoader(LOADER_ID_MAILBOX_LIST, null, mMyLoaderCallbacks);
|
||||
}
|
||||
|
||||
/**
|
||||
* This is called via the activity
|
||||
* TODO This will be removed when possible
|
||||
*/
|
||||
@Override
|
||||
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo info) {
|
||||
AdapterView.AdapterContextMenuInfo menuInfo = (AdapterView.AdapterContextMenuInfo) info;
|
||||
Cursor c = (Cursor) getListView().getItemAtPosition(menuInfo.position);
|
||||
String folderName = Utility.FolderProperties.getInstance(mActivity)
|
||||
.getDisplayName(Integer.valueOf(c.getString(mListAdapter.COLUMN_TYPE)));
|
||||
if (folderName == null) {
|
||||
folderName = c.getString(mListAdapter.COLUMN_DISPLAY_NAME);
|
||||
private class MyLoaderCallbacks implements LoaderCallbacks<Cursor> {
|
||||
@Override
|
||||
public Loader<Cursor> onCreateLoader(int id, Bundle args) {
|
||||
if (Email.DEBUG_LIFECYCLE && Email.DEBUG) {
|
||||
Log.d(Email.LOG_TAG, "MailboxListFragment onCreateLoader");
|
||||
}
|
||||
return MailboxesAdapter.createLoader(getActivity(), mAccountId);
|
||||
}
|
||||
|
||||
menu.setHeaderTitle(folderName);
|
||||
mActivity.getMenuInflater().inflate(R.menu.mailbox_list_context, menu);
|
||||
}
|
||||
@Override
|
||||
public void onLoadFinished(Loader<Cursor> loader, Cursor cursor) {
|
||||
if (Email.DEBUG_LIFECYCLE && Email.DEBUG) {
|
||||
Log.d(Email.LOG_TAG, "MailboxListFragment onLoadFinished");
|
||||
}
|
||||
|
||||
/**
|
||||
* This is called via the activity
|
||||
* TODO This will be removed when possible
|
||||
*/
|
||||
@Override
|
||||
public boolean onContextItemSelected(MenuItem item) {
|
||||
AdapterView.AdapterContextMenuInfo info =
|
||||
(AdapterView.AdapterContextMenuInfo) item.getMenuInfo();
|
||||
|
||||
switch (item.getItemId()) {
|
||||
case R.id.refresh:
|
||||
mCallback.onRefresh(mAccountId, info.id);
|
||||
return true;
|
||||
case R.id.open:
|
||||
mCallback.onMailboxSelected(mAccountId, info.id);
|
||||
return true;
|
||||
final ListView lv = getListView();
|
||||
final Parcelable listState = lv.onSaveInstanceState();
|
||||
mListAdapter.changeCursor(cursor);
|
||||
setListAdapter(mListAdapter);
|
||||
setListShown(true);
|
||||
lv.onRestoreInstanceState(listState);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
|
||||
mCallback.onMailboxSelected(mAccountId, id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Async task for loading the mailboxes for a given account
|
||||
*/
|
||||
private class LoadMailboxesTask extends AsyncTask<Void, Void, Object[]> {
|
||||
|
||||
private long mAccountKey;
|
||||
|
||||
/**
|
||||
* Special constructor to cache some local info
|
||||
*/
|
||||
public LoadMailboxesTask(long accountId) {
|
||||
mAccountKey = accountId;
|
||||
mDraftMailboxKey = -1;
|
||||
mTrashMailboxKey = -1;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Object[] doInBackground(Void... params) {
|
||||
long draftMailboxKey = -1;
|
||||
long trashMailboxKey = -1;
|
||||
Cursor c = mActivity.managedQuery(
|
||||
EmailContent.Mailbox.CONTENT_URI,
|
||||
mListAdapter.PROJECTION,
|
||||
MAILBOX_SELECTION,
|
||||
new String[] { String.valueOf(mAccountKey) },
|
||||
MailboxColumns.TYPE + "," + MailboxColumns.DISPLAY_NAME);
|
||||
c.moveToPosition(-1);
|
||||
while (c.moveToNext()) {
|
||||
long mailboxId = c.getInt(mListAdapter.COLUMN_ID);
|
||||
switch (c.getInt(mListAdapter.COLUMN_TYPE)) {
|
||||
case Mailbox.TYPE_DRAFTS:
|
||||
draftMailboxKey = mailboxId;
|
||||
break;
|
||||
case Mailbox.TYPE_TRASH:
|
||||
trashMailboxKey = mailboxId;
|
||||
break;
|
||||
}
|
||||
}
|
||||
Object[] result = new Object[3];
|
||||
result[0] = c;
|
||||
result[1] = draftMailboxKey;
|
||||
result[2] = trashMailboxKey;
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(Object[] results) {
|
||||
if (results == null || isCancelled()) return;
|
||||
Cursor cursor = (Cursor) results[0];
|
||||
mDraftMailboxKey = (Long) results[1];
|
||||
mTrashMailboxKey = (Long) results[2];
|
||||
|
||||
if (cursor.isClosed()) return;
|
||||
mListAdapter.changeCursor(cursor);
|
||||
setListAdapter(mListAdapter);
|
||||
updateMessageCount();
|
||||
}
|
||||
}
|
||||
|
||||
private class MessageCountTask extends AsyncTask<Void, Void, int[]> {
|
||||
|
||||
@Override
|
||||
protected int[] doInBackground(Void... params) {
|
||||
int[] counts = new int[2];
|
||||
if (mDraftMailboxKey != -1) {
|
||||
counts[0] = EmailContent.count(mActivity, Message.CONTENT_URI,
|
||||
MESSAGE_MAILBOX_ID_SELECTION,
|
||||
new String[] { String.valueOf(mDraftMailboxKey)});
|
||||
} else {
|
||||
counts[0] = 0;
|
||||
}
|
||||
if (mTrashMailboxKey != -1) {
|
||||
counts[1] = EmailContent.count(mActivity, Message.CONTENT_URI,
|
||||
MESSAGE_MAILBOX_ID_SELECTION,
|
||||
new String[] { String.valueOf(mTrashMailboxKey)});
|
||||
} else {
|
||||
counts[1] = 0;
|
||||
}
|
||||
return counts;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(int[] counts) {
|
||||
if (counts == null || isCancelled()) {
|
||||
return;
|
||||
}
|
||||
int countDraft = counts[0];
|
||||
int countTrash = counts[1];
|
||||
mListAdapter.setMessageCounts(countDraft, countTrash);
|
||||
}
|
||||
}
|
||||
|
||||
private void updateMessageCount() {
|
||||
if (mAccountId == -1 || mListAdapter.getCursor() == null) {
|
||||
return;
|
||||
}
|
||||
if (mMessageCountTask != null
|
||||
&& mMessageCountTask.getStatus() != MessageCountTask.Status.FINISHED) {
|
||||
mMessageCountTask.cancel(true);
|
||||
}
|
||||
mMessageCountTask = (MessageCountTask) new MessageCountTask().execute();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,13 +16,15 @@
|
|||
|
||||
package com.android.email.activity;
|
||||
|
||||
import com.android.email.Email;
|
||||
import com.android.email.R;
|
||||
import com.android.email.Utility;
|
||||
import com.android.email.provider.EmailContent;
|
||||
import com.android.email.provider.EmailContent.Mailbox;
|
||||
import com.android.email.provider.EmailContent.MailboxColumns;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.CursorLoader;
|
||||
import android.content.Loader;
|
||||
import android.database.Cursor;
|
||||
import android.graphics.Typeface;
|
||||
import android.view.LayoutInflater;
|
||||
|
@ -34,115 +36,80 @@ import android.widget.TextView;
|
|||
|
||||
/**
|
||||
* The adapter for displaying mailboxes.
|
||||
*
|
||||
* TODO Add "combined inbox/star/etc.".
|
||||
* TODO Throttle auto-requery.
|
||||
* TODO Unit test, when UI is settled.
|
||||
*/
|
||||
/* package */ class MailboxesAdapter extends CursorAdapter {
|
||||
private static final String[] PROJECTION = new String[] { MailboxColumns.ID,
|
||||
MailboxColumns.DISPLAY_NAME, MailboxColumns.UNREAD_COUNT, MailboxColumns.TYPE,
|
||||
MailboxColumns.MESSAGE_COUNT};
|
||||
private static final int COLUMN_ID = 0;
|
||||
private static final int COLUMN_DISPLAY_NAME = 1;
|
||||
private static final int COLUMN_UNREAD_COUNT = 2;
|
||||
private static final int COLUMN_TYPE = 3;
|
||||
private static final int COLUMN_MESSAGE_COUNT = 4;
|
||||
|
||||
public final String[] PROJECTION = new String[] { MailboxColumns.ID,
|
||||
MailboxColumns.DISPLAY_NAME, MailboxColumns.UNREAD_COUNT, MailboxColumns.TYPE };
|
||||
public final int COLUMN_ID = 0;
|
||||
public final int COLUMN_DISPLAY_NAME = 1;
|
||||
public final int COLUMN_UNREAD_COUNT = 2;
|
||||
public final int COLUMN_TYPE = 3;
|
||||
private static final String MAILBOX_SELECTION = MailboxColumns.ACCOUNT_KEY + "=?" +
|
||||
" AND " + MailboxColumns.TYPE + "<" + Mailbox.TYPE_NOT_EMAIL +
|
||||
" AND " + MailboxColumns.FLAG_VISIBLE + "=1";
|
||||
|
||||
private final LayoutInflater mInflater;
|
||||
private long mAccountId;
|
||||
private int mUnreadCountDraft;
|
||||
private int mUnreadCountTrash;
|
||||
|
||||
public MailboxesAdapter(Context context) {
|
||||
super(context, null);
|
||||
super(context, null, 0 /* no auto-requery */);
|
||||
mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set account Id (which may become available after creation)
|
||||
* TODO simplify the caller to just provide this at constructor time
|
||||
*/
|
||||
public void setAccountId(long accountId) {
|
||||
mAccountId = accountId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set special read/unread counts (not taken from the row).
|
||||
*/
|
||||
public void setMessageCounts(int numDrafts, int numTrash) {
|
||||
boolean countChanged = (mUnreadCountDraft != numDrafts) || (mUnreadCountTrash != numTrash);
|
||||
if (countChanged) {
|
||||
mUnreadCountDraft = numDrafts;
|
||||
mUnreadCountTrash = numTrash;
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void bindView(View view, Context context, Cursor cursor) {
|
||||
int type = cursor.getInt(COLUMN_TYPE);
|
||||
String text = Utility.FolderProperties.getInstance(context)
|
||||
final int type = cursor.getInt(COLUMN_TYPE);
|
||||
|
||||
// Set mailbox name
|
||||
final TextView nameView = (TextView) view.findViewById(R.id.mailbox_name);
|
||||
String mailboxName = Utility.FolderProperties.getInstance(context)
|
||||
.getDisplayName(type);
|
||||
if (text == null) {
|
||||
text = cursor.getString(COLUMN_DISPLAY_NAME);
|
||||
if (mailboxName == null) {
|
||||
mailboxName = cursor.getString(COLUMN_DISPLAY_NAME);
|
||||
}
|
||||
TextView nameView = (TextView) view.findViewById(R.id.mailbox_name);
|
||||
if (text != null) {
|
||||
nameView.setText(text);
|
||||
if (mailboxName != null) {
|
||||
nameView.setText(mailboxName);
|
||||
}
|
||||
|
||||
// TODO get/track live folder status
|
||||
text = null;
|
||||
TextView statusView = (TextView) view.findViewById(R.id.mailbox_status);
|
||||
if (text != null) {
|
||||
statusView.setText(text);
|
||||
statusView.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
statusView.setVisibility(View.GONE);
|
||||
}
|
||||
View chipView = view.findViewById(R.id.chip);
|
||||
chipView.setBackgroundResource(Email.getAccountColorResourceId(mAccountId));
|
||||
int count = -1;
|
||||
switch (type) {
|
||||
case Mailbox.TYPE_DRAFTS:
|
||||
count = mUnreadCountDraft;
|
||||
text = String.valueOf(count);
|
||||
break;
|
||||
case Mailbox.TYPE_TRASH:
|
||||
count = mUnreadCountTrash;
|
||||
text = String.valueOf(count);
|
||||
break;
|
||||
default:
|
||||
text = cursor.getString(COLUMN_UNREAD_COUNT);
|
||||
if (text != null) {
|
||||
count = Integer.valueOf(text);
|
||||
}
|
||||
break;
|
||||
}
|
||||
TextView unreadCountView = (TextView) view.findViewById(R.id.new_message_count);
|
||||
TextView allCountView = (TextView) view.findViewById(R.id.all_message_count);
|
||||
// Set count
|
||||
final int count = cursor.getInt((type == Mailbox.TYPE_DRAFTS || type == Mailbox.TYPE_TRASH)
|
||||
? COLUMN_MESSAGE_COUNT : COLUMN_UNREAD_COUNT);
|
||||
final TextView unreadCountView = (TextView) view.findViewById(R.id.new_message_count);
|
||||
final TextView allCountView = (TextView) view.findViewById(R.id.all_message_count);
|
||||
|
||||
// If the unread count is zero, not to show countView.
|
||||
if (count > 0) {
|
||||
nameView.setTypeface(Typeface.DEFAULT_BOLD);
|
||||
switch (type) {
|
||||
case Mailbox.TYPE_DRAFTS:
|
||||
case Mailbox.TYPE_OUTBOX:
|
||||
case Mailbox.TYPE_SENT:
|
||||
case Mailbox.TYPE_TRASH:
|
||||
unreadCountView.setVisibility(View.GONE);
|
||||
allCountView.setVisibility(View.VISIBLE);
|
||||
allCountView.setText(text);
|
||||
break;
|
||||
default:
|
||||
allCountView.setVisibility(View.GONE);
|
||||
unreadCountView.setVisibility(View.VISIBLE);
|
||||
unreadCountView.setText(text);
|
||||
break;
|
||||
}
|
||||
case Mailbox.TYPE_DRAFTS:
|
||||
case Mailbox.TYPE_OUTBOX:
|
||||
case Mailbox.TYPE_SENT:
|
||||
case Mailbox.TYPE_TRASH:
|
||||
unreadCountView.setVisibility(View.GONE);
|
||||
allCountView.setVisibility(View.VISIBLE);
|
||||
allCountView.setText(Integer.toString(count));
|
||||
break;
|
||||
default:
|
||||
allCountView.setVisibility(View.GONE);
|
||||
unreadCountView.setVisibility(View.VISIBLE);
|
||||
unreadCountView.setText(Integer.toString(count));
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
nameView.setTypeface(Typeface.DEFAULT);
|
||||
allCountView.setVisibility(View.GONE);
|
||||
unreadCountView.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
ImageView folderIcon = (ImageView) view.findViewById(R.id.folder_icon);
|
||||
folderIcon.setImageDrawable(Utility.FolderProperties.getInstance(context)
|
||||
// Set folder icon
|
||||
((ImageView) view.findViewById(R.id.folder_icon))
|
||||
.setImageDrawable(Utility.FolderProperties.getInstance(context)
|
||||
.getIconIds(type));
|
||||
}
|
||||
|
||||
|
@ -150,4 +117,16 @@ import android.widget.TextView;
|
|||
public View newView(Context context, Cursor cursor, ViewGroup parent) {
|
||||
return mInflater.inflate(R.layout.mailbox_list_item, parent, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mailboxes Loader for an account.
|
||||
*/
|
||||
public static Loader<Cursor> createLoader(Context context, long accountId) {
|
||||
return new CursorLoader(context,
|
||||
EmailContent.Mailbox.CONTENT_URI,
|
||||
MailboxesAdapter.PROJECTION,
|
||||
MAILBOX_SELECTION,
|
||||
new String[] { String.valueOf(accountId) },
|
||||
MailboxColumns.TYPE + "," + MailboxColumns.DISPLAY_NAME);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue